PageSourceSearch

https://hrinhealth.com.au/app/plugins/learndash-propanel/assets/dist/js/public.js?ver=3.0.5

js hrinhealth.com.au collected 2026-10-06 00:26:09 UTC 1,097,816 bytes, 34,925 lines download raw bytes

vendor: 5,117 bytes, lines 1-134
1/******/ (function(modules) { // webpackBootstrap
2/******/ 	// The module cache
3/******/ 	var installedModules = {};
4/******/
5/******/ 	// The require function
6/******/ 	function __webpack_require__(moduleId) {
7/******/
8/******/ 		// Check if module is in cache
9/******/ 		if(installedModules[moduleId]) {
10/******/ 			return installedModules[moduleId].exports;
11/******/ 		}
12/******/ 		// Create a new module (and put it into the cache)
13/******/ 		var module = installedModules[moduleId] = {
14/******/ 			i: moduleId,
15/******/ 			l: false,
16/******/ 			exports: {}
17/******/ 		};
18/******/
19/******/ 		// Execute the module function
20/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21/******/
22/******/ 		// Flag the module as loaded
23/******/ 		module.l = true;
24/******/
25/******/ 		// Return the exports of the module
26/******/ 		return module.exports;
27/******/ 	}
28/******/
29/******/
30/******/ 	// expose the modules object (__webpack_modules__)
31/******/ 	__webpack_require__.m = modules;
32/******/
33/******/ 	// expose the module cache
34/******/ 	__webpack_require__.c = installedModules;
35/******/
36/******/ 	// define getter function for harmony exports
37/******/ 	__webpack_require__.d = function(exports, name, getter) {
38/******/ 		if(!__webpack_require__.o(exports, name)) {
39/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
40/******/ 		}
41/******/ 	};
42/******/
43/******/ 	// define __esModule on exports
44/******/ 	__webpack_require__.r = function(exports) {
45/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
46/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
47/******/ 		}
48/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
49/******/ 	};
50/******/
51/******/ 	// create a fake namespace object
52/******/ 	// mode & 1: value is a module id, require it
53/******/ 	// mode & 2: merge all properties of value into the ns
54/******/ 	// mode & 4: return value when already ns object
55/******/ 	// mode & 8|1: behave like require
56/******/ 	__webpack_require__.t = function(value, mode) {
57/******/ 		if(mode & 1) value = __webpack_require__(value);
58/******/ 		if(mode & 8) return value;
59/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
60/******/ 		var ns = Object.create(null);
61/******/ 		__webpack_require__.r(ns);
62/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
63/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
64/******/ 		return ns;
65/******/ 	};
66/******/
67/******/ 	// getDefaultExport function for compatibility with non-harmony modules
68/******/ 	__webpack_require__.n = function(module) {
69/******/ 		var getter = module && module.__esModule ?
70/******/ 			function getDefault() { return module['default']; } :
71/******/ 			function getModuleExports() { return module; };
72/******/ 		__webpack_require__.d(getter, 'a', getter);
73/******/ 		return getter;
74/******/ 	};
75/******/
76/******/ 	// Object.prototype.hasOwnProperty.call
77/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
78/******/
79/******/ 	// __webpack_public_path__
80/******/ 	__webpack_require__.p = "";
81/******/
82/******/
83/******/ 	// Load entry module and return exports
84/******/ 	return __webpack_require__(__webpack_require__.s = 7);
85/******/ })
86/************************************************************************/
87/******/ ([
88/* 0 */
89/***/ (function(module, exports, __webpack_require__) {
90
91var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
92 * jQuery JavaScript Library v3.6.0
93 * https://jquery.com/
94 *
95 * Includes Sizzle.js
96 * https://sizzlejs.com/
97 *
98 * Copyright OpenJS Foundation and other contributors
99 * Released under the MIT license
100 * https://jquery.org/license
101 *
102 * Date: 2021-03-02T17:08Z
103 */
104( function( global, factory ) {
105
106	"use strict";
107
108	if (  true && typeof module.exports === "object" ) {
109
110		// For CommonJS and CommonJS-like environments where a proper `window`
111		// is present, execute the factory and get jQuery.
112		// For environments that do not have a `window` with a `document`
113		// (such as Node.js), expose a factory as module.exports.
114		// This accentuates the need for the creation of a real `window`.
115		// e.g. var jQuery = require("jquery")(window);
116		// See ticket #14549 for more info.
117		module.exports = global.document ?
118			factory( global, true ) :
119			function( w ) {
120				if ( !w.document ) {
121					throw new Error( "jQuery requires a window with a document" );
122				}
123				return factory( w );
124			};
125	} else {
126		factory( global );
127	}
128
129// Pass this if window is not defined yet
130} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
131
132// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
133// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
134// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), str
vendor: 2,883 bytes, lines 134-244
134ict mode should be common
135// enough that all such attempts are guarded in a try block.
136"use strict";
137
138var arr = [];
139
140var getProto = Object.getPrototypeOf;
141
142var slice = arr.slice;
143
144var flat = arr.flat ? function( array ) {
145	return arr.flat.call( array );
146} : function( array ) {
147	return arr.concat.apply( [], array );
148};
149
150
151var push = arr.push;
152
153var indexOf = arr.indexOf;
154
155var class2type = {};
156
157var toString = class2type.toString;
158
159var hasOwn = class2type.hasOwnProperty;
160
161var fnToString = hasOwn.toString;
162
163var ObjectFunctionString = fnToString.call( Object );
164
165var support = {};
166
167var isFunction = function isFunction( obj ) {
168
169		// Support: Chrome <=57, Firefox <=52
170		// In some browsers, typeof returns "function" for HTML <object> elements
171		// (i.e., `typeof document.createElement( "object" ) === "function"`).
172		// We don't want to classify *any* DOM node as a function.
173		// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
174		// Plus for old WebKit, typeof returns "function" for HTML collections
175		// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
176		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
177			typeof obj.item !== "function";
178	};
179
180
181var isWindow = function isWindow( obj ) {
182		return obj != null && obj === obj.window;
183	};
184
185
186var document = window.document;
187
188
189
190	var preservedScriptAttributes = {
191		type: true,
192		src: true,
193		nonce: true,
194		noModule: true
195	};
196
197	function DOMEval( code, node, doc ) {
198		doc = doc || document;
199
200		var i, val,
201			script = doc.createElement( "script" );
202
203		script.text = code;
204		if ( node ) {
205			for ( i in preservedScriptAttributes ) {
206
207				// Support: Firefox 64+, Edge 18+
208				// Some browsers don't support the "nonce" property on scripts.
209				// On the other hand, just using `getAttribute` is not enough as
210				// the `nonce` attribute is reset to an empty string whenever it
211				// becomes browsing-context connected.
212				// See https://github.com/whatwg/html/issues/2369
213				// See https://html.spec.whatwg.org/#nonce-attributes
214				// The `node.getAttribute` check was added for the sake of
215				// `jQuery.globalEval` so that it can fake a nonce-containing node
216				// via an object.
217				val = node[ i ] || node.getAttribute && node.getAttribute( i );
218				if ( val ) {
219					script.setAttribute( i, val );
220				}
221			}
222		}
223		doc.head.appendChild( script ).parentNode.removeChild( script );
224	}
225
226
227function toType( obj ) {
228	if ( obj == null ) {
229		return obj + "";
230	}
231
232	// Support: Android <=2.3 only (functionish RegExp)
233	return typeof obj === "object" || typeof obj === "function" ?
234		class2type[ toString.call( obj ) ] || "object" :
235		typeof obj;
236}
237/* global Symbol */
238// Defining this global in .eslintrc.json would create a danger of using the global
239// unguarded in another place, it seems safer to define global only for this module
240
241
242
243var
244	version = "3.6.0
vendor: 183,283 bytes, lines 244-7039
244",
245
246	// Define a local copy of jQuery
247	jQuery = function( selector, context ) {
248
249		// The jQuery object is actually just the init constructor 'enhanced'
250		// Need init if jQuery is called (just allow error to be thrown if not included)
251		return new jQuery.fn.init( selector, context );
252	};
253
254jQuery.fn = jQuery.prototype = {
255
256	// The current version of jQuery being used
257	jquery: version,
258
259	constructor: jQuery,
260
261	// The default length of a jQuery object is 0
262	length: 0,
263
264	toArray: function() {
265		return slice.call( this );
266	},
267
268	// Get the Nth element in the matched element set OR
269	// Get the whole matched element set as a clean array
270	get: function( num ) {
271
272		// Return all the elements in a clean array
273		if ( num == null ) {
274			return slice.call( this );
275		}
276
277		// Return just the one element from the set
278		return num < 0 ? this[ num + this.length ] : this[ num ];
279	},
280
281	// Take an array of elements and push it onto the stack
282	// (returning the new matched element set)
283	pushStack: function( elems ) {
284
285		// Build a new jQuery matched element set
286		var ret = jQuery.merge( this.constructor(), elems );
287
288		// Add the old object onto the stack (as a reference)
289		ret.prevObject = this;
290
291		// Return the newly-formed element set
292		return ret;
293	},
294
295	// Execute a callback for every element in the matched set.
296	each: function( callback ) {
297		return jQuery.each( this, callback );
298	},
299
300	map: function( callback ) {
301		return this.pushStack( jQuery.map( this, function( elem, i ) {
302			return callback.call( elem, i, elem );
303		} ) );
304	},
305
306	slice: function() {
307		return this.pushStack( slice.apply( this, arguments ) );
308	},
309
310	first: function() {
311		return this.eq( 0 );
312	},
313
314	last: function() {
315		return this.eq( -1 );
316	},
317
318	even: function() {
319		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
320			return ( i + 1 ) % 2;
321		} ) );
322	},
323
324	odd: function() {
325		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
326			return i % 2;
327		} ) );
328	},
329
330	eq: function( i ) {
331		var len = this.length,
332			j = +i + ( i < 0 ? len : 0 );
333		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
334	},
335
336	end: function() {
337		return this.prevObject || this.constructor();
338	},
339
340	// For internal use only.
341	// Behaves like an Array's method, not like a jQuery method.
342	push: push,
343	sort: arr.sort,
344	splice: arr.splice
345};
346
347jQuery.extend = jQuery.fn.extend = function() {
348	var options, name, src, copy, copyIsArray, clone,
349		target = arguments[ 0 ] || {},
350		i = 1,
351		length = arguments.length,
352		deep = false;
353
354	// Handle a deep copy situation
355	if ( typeof target === "boolean" ) {
356		deep = target;
357
358		// Skip the boolean and the target
359		target = arguments[ i ] || {};
360		i++;
361	}
362
363	// Handle case when target is a string or something (possible in deep copy)
364	if ( typeof target !== "object" && !isFunction( target ) ) {
365		target = {};
366	}
367
368	// Extend jQuery itself if only one argument is passed
369	if ( i === length ) {
370		target = this;
371		i--;
372	}
373
374	for ( ; i < length; i++ ) {
375
376		// Only deal with non-null/undefined values
377		if ( ( options = arguments[ i ] ) != null ) {
378
379			// Extend the base object
380			for ( name in options ) {
381				copy = options[ name ];
382
383				// Prevent Object.prototype pollution
384				// Prevent never-ending loop
385				if ( name === "__proto__" || target === copy ) {
386					continue;
387				}
388
389				// Recurse if we're merging plain objects or arrays
390				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
391					( copyIsArray = Array.isArray( copy ) ) ) ) {
392					src = target[ name ];
393
394					// Ensure proper type for the source value
395					if ( copyIsArray && !Array.isArray( src ) ) {
396						clone = [];
397					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
398						clone = {};
399					} else {
400						clone = src;
401					}
402					copyIsArray = false;
403
404					// Never move original objects, clone them
405					target[ name ] = jQuery.extend( deep, clone, copy );
406
407				// Don't bring in undefined values
408				} else if ( copy !== undefined ) {
409					target[ name ] = copy;
410				}
411			}
412		}
413	}
414
415	// Return the modified object
416	return target;
417};
418
419jQuery.extend( {
420
421	// Unique for each copy of jQuery on the page
422	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
423
424	// Assume jQuery is ready without the ready module
425	isReady: true,
426
427	error: function( msg ) {
428		throw new Error( msg );
429	},
430
431	noop: function() {},
432
433	isPlainObject: function( obj ) {
434		var proto, Ctor;
435
436		// Detect obvious negatives
437		// Use toString instead of jQuery.type to catch host objects
438		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
439			return false;
440		}
441
442		proto = getProto( obj );
443
444		// Objects with no prototype (e.g., `Object.create( null )`) are plain
445		if ( !proto ) {
446			return true;
447		}
448
449		// Objects with prototype are plain iff they were constructed by a global Object function
450		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
451		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
452	},
453
454	isEmptyObject: function( obj ) {
455		var name;
456
457		for ( name in obj ) {
458			return false;
459		}
460		return true;
461	},
462
463	// Evaluates a script in a provided context; falls back to the global one
464	// if not specified.
465	globalEval: function( code, options, doc ) {
466		DOMEval( code, { nonce: options && options.nonce }, doc );
467	},
468
469	each: function( obj, callback ) {
470		var length, i = 0;
471
472		if ( isArrayLike( obj ) ) {
473			length = obj.length;
474			for ( ; i < length; i++ ) {
475				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
476					break;
477				}
478			}
479		} else {
480			for ( i in obj ) {
481				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
482					break;
483				}
484			}
485		}
486
487		return obj;
488	},
489
490	// results is for internal usage only
491	makeArray: function( arr, results ) {
492		var ret = results || [];
493
494		if ( arr != null ) {
495			if ( isArrayLike( Object( arr ) ) ) {
496				jQuery.merge( ret,
497					typeof arr === "string" ?
498						[ arr ] : arr
499				);
500			} else {
501				push.call( ret, arr );
502			}
503		}
504
505		return ret;
506	},
507
508	inArray: function( elem, arr, i ) {
509		return arr == null ? -1 : indexOf.call( arr, elem, i );
510	},
511
512	// Support: Android <=4.0 only, PhantomJS 1 only
513	// push.apply(_, arraylike) throws on ancient WebKit
514	merge: function( first, second ) {
515		var len = +second.length,
516			j = 0,
517			i = first.length;
518
519		for ( ; j < len; j++ ) {
520			first[ i++ ] = second[ j ];
521		}
522
523		first.length = i;
524
525		return first;
526	},
527
528	grep: function( elems, callback, invert ) {
529		var callbackInverse,
530			matches = [],
531			i = 0,
532			length = elems.length,
533			callbackExpect = !invert;
534
535		// Go through the array, only saving the items
536		// that pass the validator function
537		for ( ; i < length; i++ ) {
538			callbackInverse = !callback( elems[ i ], i );
539			if ( callbackInverse !== callbackExpect ) {
540				matches.push( elems[ i ] );
541			}
542		}
543
544		return matches;
545	},
546
547	// arg is for internal usage only
548	map: function( elems, callback, arg ) {
549		var length, value,
550			i = 0,
551			ret = [];
552
553		// Go through the array, translating each of the items to their new values
554		if ( isArrayLike( elems ) ) {
555			length = elems.length;
556			for ( ; i < length; i++ ) {
557				value = callback( elems[ i ], i, arg );
558
559				if ( value != null ) {
560					ret.push( value );
561				}
562			}
563
564		// Go through every key on the object,
565		} else {
566			for ( i in elems ) {
567				value = callback( elems[ i ], i, arg );
568
569				if ( value != null ) {
570					ret.push( value );
571				}
572			}
573		}
574
575		// Flatten any nested arrays
576		return flat( ret );
577	},
578
579	// A global GUID counter for objects
580	guid: 1,
581
582	// jQuery.support is not used in Core but other projects attach their
583	// properties to it so it needs to exist.
584	support: support
585} );
586
587if ( typeof Symbol === "function" ) {
588	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
589}
590
591// Populate the class2type map
592jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
593	function( _i, name ) {
594		class2type[ "[object " + name + "]" ] = name.toLowerCase();
595	} );
596
597function isArrayLike( obj ) {
598
599	// Support: real iOS 8.2 only (not reproducible in simulator)
600	// `in` check used to prevent JIT error (gh-2145)
601	// hasOwn isn't used here due to false negatives
602	// regarding Nodelist length in IE
603	var length = !!obj && "length" in obj && obj.length,
604		type = toType( obj );
605
606	if ( isFunction( obj ) || isWindow( obj ) ) {
607		return false;
608	}
609
610	return type === "array" || length === 0 ||
611		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
612}
613var Sizzle =
614/*!
615 * Sizzle CSS Selector Engine v2.3.6
616 * https://sizzlejs.com/
617 *
618 * Copyright JS Foundation and other contributors
619 * Released under the MIT license
620 * https://js.foundation/
621 *
622 * Date: 2021-02-16
623 */
624( function( window ) {
625var i,
626	support,
627	Expr,
628	getText,
629	isXML,
630	tokenize,
631	compile,
632	select,
633	outermostContext,
634	sortInput,
635	hasDuplicate,
636
637	// Local document vars
638	setDocument,
639	document,
640	docElem,
641	documentIsHTML,
642	rbuggyQSA,
643	rbuggyMatches,
644	matches,
645	contains,
646
647	// Instance-specific data
648	expando = "sizzle" + 1 * new Date(),
649	preferredDoc = window.document,
650	dirruns = 0,
651	done = 0,
652	classCache = createCache(),
653	tokenCache = createCache(),
654	compilerCache = createCache(),
655	nonnativeSelectorCache = createCache(),
656	sortOrder = function( a, b ) {
657		if ( a === b ) {
658			hasDuplicate = true;
659		}
660		return 0;
661	},
662
663	// Instance methods
664	hasOwn = ( {} ).hasOwnProperty,
665	arr = [],
666	pop = arr.pop,
667	pushNative = arr.push,
668	push = arr.push,
669	slice = arr.slice,
670
671	// Use a stripped-down indexOf as it's faster than native
672	// https://jsperf.com/thor-indexof-vs-for/5
673	indexOf = function( list, elem ) {
674		var i = 0,
675			len = list.length;
676		for ( ; i < len; i++ ) {
677			if ( list[ i ] === elem ) {
678				return i;
679			}
680		}
681		return -1;
682	},
683
684	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
685		"ismap|loop|multiple|open|readonly|required|scoped",
686
687	// Regular expressions
688
689	// http://www.w3.org/TR/css3-selectors/#whitespace
690	whitespace = "[\\x20\\t\\r\\n\\f]",
691
692	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
693	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
694		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
695
696	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
697	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
698
699		// Operator (capture 2)
700		"*([*^$|!~]?=)" + whitespace +
701
702		// "Attribute values must be CSS identifiers [capture 5]
703		// or strings [capture 3 or capture 4]"
704		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
705		whitespace + "*\\]",
706
707	pseudos = ":(" + identifier + ")(?:\\((" +
708
709		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
710		// 1. quoted (capture 3; capture 4 or capture 5)
711		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
712
713		// 2. simple (capture 6)
714		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
715
716		// 3. anything else (capture 2)
717		".*" +
718		")\\)|)",
719
720	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
721	rwhitespace = new RegExp( whitespace + "+", "g" ),
722	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
723		whitespace + "+$", "g" ),
724
725	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
726	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
727		"*" ),
728	rdescend = new RegExp( whitespace + "|>" ),
729
730	rpseudo = new RegExp( pseudos ),
731	ridentifier = new RegExp( "^" + identifier + "$" ),
732
733	matchExpr = {
734		"ID": new RegExp( "^#(" + identifier + ")" ),
735		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
736		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
737		"ATTR": new RegExp( "^" + attributes ),
738		"PSEUDO": new RegExp( "^" + pseudos ),
739		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
740			whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
741			whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
742		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
743
744		// For use in libraries implementing .is()
745		// We use this for POS matching in `select`
746		"needsContext": new RegExp( "^" + whitespace +
747			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
748			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
749	},
750
751	rhtml = /HTML$/i,
752	rinputs = /^(?:input|select|textarea|button)$/i,
753	rheader = /^h\d$/i,
754
755	rnative = /^[^{]+\{\s*\[native \w/,
756
757	// Easily-parseable/retrievable ID or TAG or CLASS selectors
758	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
759
760	rsibling = /[+~]/,
761
762	// CSS escapes
763	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
764	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
765	funescape = function( escape, nonHex ) {
766		var high = "0x" + escape.slice( 1 ) - 0x10000;
767
768		return nonHex ?
769
770			// Strip the backslash prefix from a non-hex escape sequence
771			nonHex :
772
773			// Replace a hexadecimal escape sequence with the encoded Unicode code point
774			// Support: IE <=11+
775			// For values outside the Basic Multilingual Plane (BMP), manually construct a
776			// surrogate pair
777			high < 0 ?
778				String.fromCharCode( high + 0x10000 ) :
779				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
780	},
781
782	// CSS string/identifier serialization
783	// https://drafts.csswg.org/cssom/#common-serializing-idioms
784	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
785	fcssescape = function( ch, asCodePoint ) {
786		if ( asCodePoint ) {
787
788			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
789			if ( ch === "\0" ) {
790				return "\uFFFD";
791			}
792
793			// Control characters and (dependent upon position) numbers get escaped as code points
794			return ch.slice( 0, -1 ) + "\\" +
795				ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
796		}
797
798		// Other potentially-special ASCII characters get backslash-escaped
799		return "\\" + ch;
800	},
801
802	// Used for iframes
803	// See setDocument()
804	// Removing the function wrapper causes a "Permission Denied"
805	// error in IE
806	unloadHandler = function() {
807		setDocument();
808	},
809
810	inDisabledFieldset = addCombinator(
811		function( elem ) {
812			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
813		},
814		{ dir: "parentNode", next: "legend" }
815	);
816
817// Optimize for push.apply( _, NodeList )
818try {
819	push.apply(
820		( arr = slice.call( preferredDoc.childNodes ) ),
821		preferredDoc.childNodes
822	);
823
824	// Support: Android<4.0
825	// Detect silently failing push.apply
826	// eslint-disable-next-line no-unused-expressions
827	arr[ preferredDoc.childNodes.length ].nodeType;
828} catch ( e ) {
829	push = { apply: arr.length ?
830
831		// Leverage slice if possible
832		function( target, els ) {
833			pushNative.apply( target, slice.call( els ) );
834		} :
835
836		// Support: IE<9
837		// Otherwise append directly
838		function( target, els ) {
839			var j = target.length,
840				i = 0;
841
842			// Can't trust NodeList.length
843			while ( ( target[ j++ ] = els[ i++ ] ) ) {}
844			target.length = j - 1;
845		}
846	};
847}
848
849function Sizzle( selector, context, results, seed ) {
850	var m, i, elem, nid, match, groups, newSelector,
851		newContext = context && context.ownerDocument,
852
853		// nodeType defaults to 9, since context defaults to document
854		nodeType = context ? context.nodeType : 9;
855
856	results = results || [];
857
858	// Return early from calls with invalid selector or context
859	if ( typeof selector !== "string" || !selector ||
860		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
861
862		return results;
863	}
864
865	// Try to shortcut find operations (as opposed to filters) in HTML documents
866	if ( !seed ) {
867		setDocument( context );
868		context = context || document;
869
870		if ( documentIsHTML ) {
871
872			// If the selector is sufficiently simple, try using a "get*By*" DOM method
873			// (excepting DocumentFragment context, where the methods don't exist)
874			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
875
876				// ID selector
877				if ( ( m = match[ 1 ] ) ) {
878
879					// Document context
880					if ( nodeType === 9 ) {
881						if ( ( elem = context.getElementById( m ) ) ) {
882
883							// Support: IE, Opera, Webkit
884							// TODO: identify versions
885							// getElementById can match elements by name instead of ID
886							if ( elem.id === m ) {
887								results.push( elem );
888								return results;
889							}
890						} else {
891							return results;
892						}
893
894					// Element context
895					} else {
896
897						// Support: IE, Opera, Webkit
898						// TODO: identify versions
899						// getElementById can match elements by name instead of ID
900						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
901							contains( context, elem ) &&
902							elem.id === m ) {
903
904							results.push( elem );
905							return results;
906						}
907					}
908
909				// Type selector
910				} else if ( match[ 2 ] ) {
911					push.apply( results, context.getElementsByTagName( selector ) );
912					return results;
913
914				// Class selector
915				} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
916					context.getElementsByClassName ) {
917
918					push.apply( results, context.getElementsByClassName( m ) );
919					return results;
920				}
921			}
922
923			// Take advantage of querySelectorAll
924			if ( support.qsa &&
925				!nonnativeSelectorCache[ selector + " " ] &&
926				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
927
928				// Support: IE 8 only
929				// Exclude object elements
930				( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
931
932				newSelector = selector;
933				newContext = context;
934
935				// qSA considers elements outside a scoping root when evaluating child or
936				// descendant combinators, which is not what we want.
937				// In such cases, we work around the behavior by prefixing every selector in the
938				// list with an ID selector referencing the scope context.
939				// The technique has to be used as well when a leading combinator is used
940				// as such selectors are not recognized by querySelectorAll.
941				// Thanks to Andrew Dupont for this technique.
942				if ( nodeType === 1 &&
943					( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
944
945					// Expand context for sibling selectors
946					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
947						context;
948
949					// We can use :scope instead of the ID hack if the browser
950					// supports it & if we're not changing the context.
951					if ( newContext !== context || !support.scope ) {
952
953						// Capture the context ID, setting it first if necessary
954						if ( ( nid = context.getAttribute( "id" ) ) ) {
955							nid = nid.replace( rcssescape, fcssescape );
956						} else {
957							context.setAttribute( "id", ( nid = expando ) );
958						}
959					}
960
961					// Prefix every selector in the list
962					groups = tokenize( selector );
963					i = groups.length;
964					while ( i-- ) {
965						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
966							toSelector( groups[ i ] );
967					}
968					newSelector = groups.join( "," );
969				}
970
971				try {
972					push.apply( results,
973						newContext.querySelectorAll( newSelector )
974					);
975					return results;
976				} catch ( qsaError ) {
977					nonnativeSelectorCache( selector, true );
978				} finally {
979					if ( nid === expando ) {
980						context.removeAttribute( "id" );
981					}
982				}
983			}
984		}
985	}
986
987	// All others
988	return select( selector.replace( rtrim, "$1" ), context, results, seed );
989}
990
991/**
992 * Create key-value caches of limited size
993 * @returns {function(string, object)} Returns the Object data after storing it on itself with
994 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
995 *	deleting the oldest entry
996 */
997function createCache() {
998	var keys = [];
999
1000	function cache( key, value ) {
1001
1002		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
1003		if ( keys.push( key + " " ) > Expr.cacheLength ) {
1004
1005			// Only keep the most recent entries
1006			delete cache[ keys.shift() ];
1007		}
1008		return ( cache[ key + " " ] = value );
1009	}
1010	return cache;
1011}
1012
1013/**
1014 * Mark a function for special use by Sizzle
1015 * @param {Function} fn The function to mark
1016 */
1017function markFunction( fn ) {
1018	fn[ expando ] = true;
1019	return fn;
1020}
1021
1022/**
1023 * Support testing using an element
1024 * @param {Function} fn Passed the created element and returns a boolean result
1025 */
1026function assert( fn ) {
1027	var el = document.createElement( "fieldset" );
1028
1029	try {
1030		return !!fn( el );
1031	} catch ( e ) {
1032		return false;
1033	} finally {
1034
1035		// Remove from its parent by default
1036		if ( el.parentNode ) {
1037			el.parentNode.removeChild( el );
1038		}
1039
1040		// release memory in IE
1041		el = null;
1042	}
1043}
1044
1045/**
1046 * Adds the same handler for all of the specified attrs
1047 * @param {String} attrs Pipe-separated list of attributes
1048 * @param {Function} handler The method that will be applied
1049 */
1050function addHandle( attrs, handler ) {
1051	var arr = attrs.split( "|" ),
1052		i = arr.length;
1053
1054	while ( i-- ) {
1055		Expr.attrHandle[ arr[ i ] ] = handler;
1056	}
1057}
1058
1059/**
1060 * Checks document order of two siblings
1061 * @param {Element} a
1062 * @param {Element} b
1063 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1064 */
1065function siblingCheck( a, b ) {
1066	var cur = b && a,
1067		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
1068			a.sourceIndex - b.sourceIndex;
1069
1070	// Use IE sourceIndex if available on both nodes
1071	if ( diff ) {
1072		return diff;
1073	}
1074
1075	// Check if b follows a
1076	if ( cur ) {
1077		while ( ( cur = cur.nextSibling ) ) {
1078			if ( cur === b ) {
1079				return -1;
1080			}
1081		}
1082	}
1083
1084	return a ? 1 : -1;
1085}
1086
1087/**
1088 * Returns a function to use in pseudos for input types
1089 * @param {String} type
1090 */
1091function createInputPseudo( type ) {
1092	return function( elem ) {
1093		var name = elem.nodeName.toLowerCase();
1094		return name === "input" && elem.type === type;
1095	};
1096}
1097
1098/**
1099 * Returns a function to use in pseudos for buttons
1100 * @param {String} type
1101 */
1102function createButtonPseudo( type ) {
1103	return function( elem ) {
1104		var name = elem.nodeName.toLowerCase();
1105		return ( name === "input" || name === "button" ) && elem.type === type;
1106	};
1107}
1108
1109/**
1110 * Returns a function to use in pseudos for :enabled/:disabled
1111 * @param {Boolean} disabled true for :disabled; false for :enabled
1112 */
1113function createDisabledPseudo( disabled ) {
1114
1115	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1116	return function( elem ) {
1117
1118		// Only certain elements can match :enabled or :disabled
1119		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1120		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1121		if ( "form" in elem ) {
1122
1123			// Check for inherited disabledness on relevant non-disabled elements:
1124			// * listed form-associated elements in a disabled fieldset
1125			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1126			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1127			// * option elements in a disabled optgroup
1128			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1129			// All such elements have a "form" property.
1130			if ( elem.parentNode && elem.disabled === false ) {
1131
1132				// Option elements defer to a parent optgroup if present
1133				if ( "label" in elem ) {
1134					if ( "label" in elem.parentNode ) {
1135						return elem.parentNode.disabled === disabled;
1136					} else {
1137						return elem.disabled === disabled;
1138					}
1139				}
1140
1141				// Support: IE 6 - 11
1142				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
1143				return elem.isDisabled === disabled ||
1144
1145					// Where there is no isDisabled, check manually
1146					/* jshint -W018 */
1147					elem.isDisabled !== !disabled &&
1148					inDisabledFieldset( elem ) === disabled;
1149			}
1150
1151			return elem.disabled === disabled;
1152
1153		// Try to winnow out elements that can't be disabled before trusting the disabled property.
1154		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1155		// even exist on them, let alone have a boolean value.
1156		} else if ( "label" in elem ) {
1157			return elem.disabled === disabled;
1158		}
1159
1160		// Remaining elements are neither :enabled nor :disabled
1161		return false;
1162	};
1163}
1164
1165/**
1166 * Returns a function to use in pseudos for positionals
1167 * @param {Function} fn
1168 */
1169function createPositionalPseudo( fn ) {
1170	return markFunction( function( argument ) {
1171		argument = +argument;
1172		return markFunction( function( seed, matches ) {
1173			var j,
1174				matchIndexes = fn( [], seed.length, argument ),
1175				i = matchIndexes.length;
1176
1177			// Match elements found at the specified indexes
1178			while ( i-- ) {
1179				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
1180					seed[ j ] = !( matches[ j ] = seed[ j ] );
1181				}
1182			}
1183		} );
1184	} );
1185}
1186
1187/**
1188 * Checks a node for validity as a Sizzle context
1189 * @param {Element|Object=} context
1190 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1191 */
1192function testContext( context ) {
1193	return context && typeof context.getElementsByTagName !== "undefined" && context;
1194}
1195
1196// Expose support vars for convenience
1197support = Sizzle.support = {};
1198
1199/**
1200 * Detects XML nodes
1201 * @param {Element|Object} elem An element or a document
1202 * @returns {Boolean} True iff elem is a non-HTML XML node
1203 */
1204isXML = Sizzle.isXML = function( elem ) {
1205	var namespace = elem && elem.namespaceURI,
1206		docElem = elem && ( elem.ownerDocument || elem ).documentElement;
1207
1208	// Support: IE <=8
1209	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
1210	// https://bugs.jquery.com/ticket/4833
1211	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
1212};
1213
1214/**
1215 * Sets document-related variables once based on the current document
1216 * @param {Element|Object} [doc] An element or document object to use to set the document
1217 * @returns {Object} Returns the current document
1218 */
1219setDocument = Sizzle.setDocument = function( node ) {
1220	var hasCompare, subWindow,
1221		doc = node ? node.ownerDocument || node : preferredDoc;
1222
1223	// Return early if doc is invalid or already selected
1224	// Support: IE 11+, Edge 17 - 18+
1225	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1226	// two documents; shallow comparisons work.
1227	// eslint-disable-next-line eqeqeq
1228	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
1229		return document;
1230	}
1231
1232	// Update global variables
1233	document = doc;
1234	docElem = document.documentElement;
1235	documentIsHTML = !isXML( document );
1236
1237	// Support: IE 9 - 11+, Edge 12 - 18+
1238	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1239	// Support: IE 11+, Edge 17 - 18+
1240	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1241	// two documents; shallow comparisons work.
1242	// eslint-disable-next-line eqeqeq
1243	if ( preferredDoc != document &&
1244		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
1245
1246		// Support: IE 11, Edge
1247		if ( subWindow.addEventListener ) {
1248			subWindow.addEventListener( "unload", unloadHandler, false );
1249
1250		// Support: IE 9 - 10 only
1251		} else if ( subWindow.attachEvent ) {
1252			subWindow.attachEvent( "onunload", unloadHandler );
1253		}
1254	}
1255
1256	// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
1257	// Safari 4 - 5 only, Opera <=11.6 - 12.x only
1258	// IE/Edge & older browsers don't support the :scope pseudo-class.
1259	// Support: Safari 6.0 only
1260	// Safari 6.0 supports :scope but it's an alias of :root there.
1261	support.scope = assert( function( el ) {
1262		docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
1263		return typeof el.querySelectorAll !== "undefined" &&
1264			!el.querySelectorAll( ":scope fieldset div" ).length;
1265	} );
1266
1267	/* Attributes
1268	---------------------------------------------------------------------- */
1269
1270	// Support: IE<8
1271	// Verify that getAttribute really returns attributes and not properties
1272	// (excepting IE8 booleans)
1273	support.attributes = assert( function( el ) {
1274		el.className = "i";
1275		return !el.getAttribute( "className" );
1276	} );
1277
1278	/* getElement(s)By*
1279	---------------------------------------------------------------------- */
1280
1281	// Check if getElementsByTagName("*") returns only elements
1282	support.getElementsByTagName = assert( function( el ) {
1283		el.appendChild( document.createComment( "" ) );
1284		return !el.getElementsByTagName( "*" ).length;
1285	} );
1286
1287	// Support: IE<9
1288	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1289
1290	// Support: IE<10
1291	// Check if getElementById returns elements by name
1292	// The broken getElementById methods don't pick up programmatically-set names,
1293	// so use a roundabout getElementsByName test
1294	support.getById = assert( function( el ) {
1295		docElem.appendChild( el ).id = expando;
1296		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1297	} );
1298
1299	// ID filter and find
1300	if ( support.getById ) {
1301		Expr.filter[ "ID" ] = function( id ) {
1302			var attrId = id.replace( runescape, funescape );
1303			return function( elem ) {
1304				return elem.getAttribute( "id" ) === attrId;
1305			};
1306		};
1307		Expr.find[ "ID" ] = function( id, context ) {
1308			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1309				var elem = context.getElementById( id );
1310				return elem ? [ elem ] : [];
1311			}
1312		};
1313	} else {
1314		Expr.filter[ "ID" ] =  function( id ) {
1315			var attrId = id.replace( runescape, funescape );
1316			return function( elem ) {
1317				var node = typeof elem.getAttributeNode !== "undefined" &&
1318					elem.getAttributeNode( "id" );
1319				return node && node.value === attrId;
1320			};
1321		};
1322
1323		// Support: IE 6 - 7 only
1324		// getElementById is not reliable as a find shortcut
1325		Expr.find[ "ID" ] = function( id, context ) {
1326			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1327				var node, i, elems,
1328					elem = context.getElementById( id );
1329
1330				if ( elem ) {
1331
1332					// Verify the id attribute
1333					node = elem.getAttributeNode( "id" );
1334					if ( node && node.value === id ) {
1335						return [ elem ];
1336					}
1337
1338					// Fall back on getElementsByName
1339					elems = context.getElementsByName( id );
1340					i = 0;
1341					while ( ( elem = elems[ i++ ] ) ) {
1342						node = elem.getAttributeNode( "id" );
1343						if ( node && node.value === id ) {
1344							return [ elem ];
1345						}
1346					}
1347				}
1348
1349				return [];
1350			}
1351		};
1352	}
1353
1354	// Tag
1355	Expr.find[ "TAG" ] = support.getElementsByTagName ?
1356		function( tag, context ) {
1357			if ( typeof context.getElementsByTagName !== "undefined" ) {
1358				return context.getElementsByTagName( tag );
1359
1360			// DocumentFragment nodes don't have gEBTN
1361			} else if ( support.qsa ) {
1362				return context.querySelectorAll( tag );
1363			}
1364		} :
1365
1366		function( tag, context ) {
1367			var elem,
1368				tmp = [],
1369				i = 0,
1370
1371				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1372				results = context.getElementsByTagName( tag );
1373
1374			// Filter out possible comments
1375			if ( tag === "*" ) {
1376				while ( ( elem = results[ i++ ] ) ) {
1377					if ( elem.nodeType === 1 ) {
1378						tmp.push( elem );
1379					}
1380				}
1381
1382				return tmp;
1383			}
1384			return results;
1385		};
1386
1387	// Class
1388	Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
1389		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1390			return context.getElementsByClassName( className );
1391		}
1392	};
1393
1394	/* QSA/matchesSelector
1395	---------------------------------------------------------------------- */
1396
1397	// QSA and matchesSelector support
1398
1399	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1400	rbuggyMatches = [];
1401
1402	// qSa(:focus) reports false when true (Chrome 21)
1403	// We allow this because of a bug in IE8/9 that throws an error
1404	// whenever `document.activeElement` is accessed on an iframe
1405	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1406	// See https://bugs.jquery.com/ticket/13378
1407	rbuggyQSA = [];
1408
1409	if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
1410
1411		// Build QSA regex
1412		// Regex strategy adopted from Diego Perini
1413		assert( function( el ) {
1414
1415			var input;
1416
1417			// Select is set to empty string on purpose
1418			// This is to test IE's treatment of not explicitly
1419			// setting a boolean content attribute,
1420			// since its presence should be enough
1421			// https://bugs.jquery.com/ticket/12359
1422			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1423				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1424				"<option selected=''></option></select>";
1425
1426			// Support: IE8, Opera 11-12.16
1427			// Nothing should be selected when empty strings follow ^= or $= or *=
1428			// The test attribute must be unknown in Opera but "safe" for WinRT
1429			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1430			if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
1431				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1432			}
1433
1434			// Support: IE8
1435			// Boolean attributes and "value" are not treated correctly
1436			if ( !el.querySelectorAll( "[selected]" ).length ) {
1437				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1438			}
1439
1440			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1441			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1442				rbuggyQSA.push( "~=" );
1443			}
1444
1445			// Support: IE 11+, Edge 15 - 18+
1446			// IE 11/Edge don't find elements on a `[name='']` query in some cases.
1447			// Adding a temporary attribute to the document before the selection works
1448			// around the issue.
1449			// Interestingly, IE 10 & older don't seem to have the issue.
1450			input = document.createElement( "input" );
1451			input.setAttribute( "name", "" );
1452			el.appendChild( input );
1453			if ( !el.querySelectorAll( "[name='']" ).length ) {
1454				rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
1455					whitespace + "*(?:''|\"\")" );
1456			}
1457
1458			// Webkit/Opera - :checked should return selected option elements
1459			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1460			// IE8 throws error here and will not see later tests
1461			if ( !el.querySelectorAll( ":checked" ).length ) {
1462				rbuggyQSA.push( ":checked" );
1463			}
1464
1465			// Support: Safari 8+, iOS 8+
1466			// https://bugs.webkit.org/show_bug.cgi?id=136851
1467			// In-page `selector#id sibling-combinator selector` fails
1468			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1469				rbuggyQSA.push( ".#.+[+~]" );
1470			}
1471
1472			// Support: Firefox <=3.6 - 5 only
1473			// Old Firefox doesn't throw on a badly-escaped identifier.
1474			el.querySelectorAll( "\\\f" );
1475			rbuggyQSA.push( "[\\r\\n\\f]" );
1476		} );
1477
1478		assert( function( el ) {
1479			el.innerHTML = "<a href='' disabled='disabled'></a>" +
1480				"<select disabled='disabled'><option/></select>";
1481
1482			// Support: Windows 8 Native Apps
1483			// The type and name attributes are restricted during .innerHTML assignment
1484			var input = document.createElement( "input" );
1485			input.setAttribute( "type", "hidden" );
1486			el.appendChild( input ).setAttribute( "name", "D" );
1487
1488			// Support: IE8
1489			// Enforce case-sensitivity of name attribute
1490			if ( el.querySelectorAll( "[name=d]" ).length ) {
1491				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1492			}
1493
1494			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1495			// IE8 throws error here and will not see later tests
1496			if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
1497				rbuggyQSA.push( ":enabled", ":disabled" );
1498			}
1499
1500			// Support: IE9-11+
1501			// IE's :disabled selector does not pick up the children of disabled fieldsets
1502			docElem.appendChild( el ).disabled = true;
1503			if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
1504				rbuggyQSA.push( ":enabled", ":disabled" );
1505			}
1506
1507			// Support: Opera 10 - 11 only
1508			// Opera 10-11 does not throw on post-comma invalid pseudos
1509			el.querySelectorAll( "*,:x" );
1510			rbuggyQSA.push( ",.*:" );
1511		} );
1512	}
1513
1514	if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
1515		docElem.webkitMatchesSelector ||
1516		docElem.mozMatchesSelector ||
1517		docElem.oMatchesSelector ||
1518		docElem.msMatchesSelector ) ) ) ) {
1519
1520		assert( function( el ) {
1521
1522			// Check to see if it's possible to do matchesSelector
1523			// on a disconnected node (IE 9)
1524			support.disconnectedMatch = matches.call( el, "*" );
1525
1526			// This should fail with an exception
1527			// Gecko does not error, returns false instead
1528			matches.call( el, "[s!='']:x" );
1529			rbuggyMatches.push( "!=", pseudos );
1530		} );
1531	}
1532
1533	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
1534	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
1535
1536	/* Contains
1537	---------------------------------------------------------------------- */
1538	hasCompare = rnative.test( docElem.compareDocumentPosition );
1539
1540	// Element contains another
1541	// Purposefully self-exclusive
1542	// As in, an element does not contain itself
1543	contains = hasCompare || rnative.test( docElem.contains ) ?
1544		function( a, b ) {
1545			var adown = a.nodeType === 9 ? a.documentElement : a,
1546				bup = b && b.parentNode;
1547			return a === bup || !!( bup && bup.nodeType === 1 && (
1548				adown.contains ?
1549					adown.contains( bup ) :
1550					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1551			) );
1552		} :
1553		function( a, b ) {
1554			if ( b ) {
1555				while ( ( b = b.parentNode ) ) {
1556					if ( b === a ) {
1557						return true;
1558					}
1559				}
1560			}
1561			return false;
1562		};
1563
1564	/* Sorting
1565	---------------------------------------------------------------------- */
1566
1567	// Document order sorting
1568	sortOrder = hasCompare ?
1569	function( a, b ) {
1570
1571		// Flag for duplicate removal
1572		if ( a === b ) {
1573			hasDuplicate = true;
1574			return 0;
1575		}
1576
1577		// Sort on method existence if only one input has compareDocumentPosition
1578		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1579		if ( compare ) {
1580			return compare;
1581		}
1582
1583		// Calculate position if both inputs belong to the same document
1584		// Support: IE 11+, Edge 17 - 18+
1585		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1586		// two documents; shallow comparisons work.
1587		// eslint-disable-next-line eqeqeq
1588		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
1589			a.compareDocumentPosition( b ) :
1590
1591			// Otherwise we know they are disconnected
1592			1;
1593
1594		// Disconnected nodes
1595		if ( compare & 1 ||
1596			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
1597
1598			// Choose the first element that is related to our preferred document
1599			// Support: IE 11+, Edge 17 - 18+
1600			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1601			// two documents; shallow comparisons work.
1602			// eslint-disable-next-line eqeqeq
1603			if ( a == document || a.ownerDocument == preferredDoc &&
1604				contains( preferredDoc, a ) ) {
1605				return -1;
1606			}
1607
1608			// Support: IE 11+, Edge 17 - 18+
1609			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1610			// two documents; shallow comparisons work.
1611			// eslint-disable-next-line eqeqeq
1612			if ( b == document || b.ownerDocument == preferredDoc &&
1613				contains( preferredDoc, b ) ) {
1614				return 1;
1615			}
1616
1617			// Maintain original order
1618			return sortInput ?
1619				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1620				0;
1621		}
1622
1623		return compare & 4 ? -1 : 1;
1624	} :
1625	function( a, b ) {
1626
1627		// Exit early if the nodes are identical
1628		if ( a === b ) {
1629			hasDuplicate = true;
1630			return 0;
1631		}
1632
1633		var cur,
1634			i = 0,
1635			aup = a.parentNode,
1636			bup = b.parentNode,
1637			ap = [ a ],
1638			bp = [ b ];
1639
1640		// Parentless nodes are either documents or disconnected
1641		if ( !aup || !bup ) {
1642
1643			// Support: IE 11+, Edge 17 - 18+
1644			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1645			// two documents; shallow comparisons work.
1646			/* eslint-disable eqeqeq */
1647			return a == document ? -1 :
1648				b == document ? 1 :
1649				/* eslint-enable eqeqeq */
1650				aup ? -1 :
1651				bup ? 1 :
1652				sortInput ?
1653				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1654				0;
1655
1656		// If the nodes are siblings, we can do a quick check
1657		} else if ( aup === bup ) {
1658			return siblingCheck( a, b );
1659		}
1660
1661		// Otherwise we need full lists of their ancestors for comparison
1662		cur = a;
1663		while ( ( cur = cur.parentNode ) ) {
1664			ap.unshift( cur );
1665		}
1666		cur = b;
1667		while ( ( cur = cur.parentNode ) ) {
1668			bp.unshift( cur );
1669		}
1670
1671		// Walk down the tree looking for a discrepancy
1672		while ( ap[ i ] === bp[ i ] ) {
1673			i++;
1674		}
1675
1676		return i ?
1677
1678			// Do a sibling check if the nodes have a common ancestor
1679			siblingCheck( ap[ i ], bp[ i ] ) :
1680
1681			// Otherwise nodes in our document sort first
1682			// Support: IE 11+, Edge 17 - 18+
1683			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1684			// two documents; shallow comparisons work.
1685			/* eslint-disable eqeqeq */
1686			ap[ i ] == preferredDoc ? -1 :
1687			bp[ i ] == preferredDoc ? 1 :
1688			/* eslint-enable eqeqeq */
1689			0;
1690	};
1691
1692	return document;
1693};
1694
1695Sizzle.matches = function( expr, elements ) {
1696	return Sizzle( expr, null, null, elements );
1697};
1698
1699Sizzle.matchesSelector = function( elem, expr ) {
1700	setDocument( elem );
1701
1702	if ( support.matchesSelector && documentIsHTML &&
1703		!nonnativeSelectorCache[ expr + " " ] &&
1704		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1705		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1706
1707		try {
1708			var ret = matches.call( elem, expr );
1709
1710			// IE 9's matchesSelector returns false on disconnected nodes
1711			if ( ret || support.disconnectedMatch ||
1712
1713				// As well, disconnected nodes are said to be in a document
1714				// fragment in IE 9
1715				elem.document && elem.document.nodeType !== 11 ) {
1716				return ret;
1717			}
1718		} catch ( e ) {
1719			nonnativeSelectorCache( expr, true );
1720		}
1721	}
1722
1723	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1724};
1725
1726Sizzle.contains = function( context, elem ) {
1727
1728	// Set document vars if needed
1729	// Support: IE 11+, Edge 17 - 18+
1730	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1731	// two documents; shallow comparisons work.
1732	// eslint-disable-next-line eqeqeq
1733	if ( ( context.ownerDocument || context ) != document ) {
1734		setDocument( context );
1735	}
1736	return contains( context, elem );
1737};
1738
1739Sizzle.attr = function( elem, name ) {
1740
1741	// Set document vars if needed
1742	// Support: IE 11+, Edge 17 - 18+
1743	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1744	// two documents; shallow comparisons work.
1745	// eslint-disable-next-line eqeqeq
1746	if ( ( elem.ownerDocument || elem ) != document ) {
1747		setDocument( elem );
1748	}
1749
1750	var fn = Expr.attrHandle[ name.toLowerCase() ],
1751
1752		// Don't get fooled by Object.prototype properties (jQuery #13807)
1753		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1754			fn( elem, name, !documentIsHTML ) :
1755			undefined;
1756
1757	return val !== undefined ?
1758		val :
1759		support.attributes || !documentIsHTML ?
1760			elem.getAttribute( name ) :
1761			( val = elem.getAttributeNode( name ) ) && val.specified ?
1762				val.value :
1763				null;
1764};
1765
1766Sizzle.escape = function( sel ) {
1767	return ( sel + "" ).replace( rcssescape, fcssescape );
1768};
1769
1770Sizzle.error = function( msg ) {
1771	throw new Error( "Syntax error, unrecognized expression: " + msg );
1772};
1773
1774/**
1775 * Document sorting and removing duplicates
1776 * @param {ArrayLike} results
1777 */
1778Sizzle.uniqueSort = function( results ) {
1779	var elem,
1780		duplicates = [],
1781		j = 0,
1782		i = 0;
1783
1784	// Unless we *know* we can detect duplicates, assume their presence
1785	hasDuplicate = !support.detectDuplicates;
1786	sortInput = !support.sortStable && results.slice( 0 );
1787	results.sort( sortOrder );
1788
1789	if ( hasDuplicate ) {
1790		while ( ( elem = results[ i++ ] ) ) {
1791			if ( elem === results[ i ] ) {
1792				j = duplicates.push( i );
1793			}
1794		}
1795		while ( j-- ) {
1796			results.splice( duplicates[ j ], 1 );
1797		}
1798	}
1799
1800	// Clear input after sorting to release objects
1801	// See https://github.com/jquery/sizzle/pull/225
1802	sortInput = null;
1803
1804	return results;
1805};
1806
1807/**
1808 * Utility function for retrieving the text value of an array of DOM nodes
1809 * @param {Array|Element} elem
1810 */
1811getText = Sizzle.getText = function( elem ) {
1812	var node,
1813		ret = "",
1814		i = 0,
1815		nodeType = elem.nodeType;
1816
1817	if ( !nodeType ) {
1818
1819		// If no nodeType, this is expected to be an array
1820		while ( ( node = elem[ i++ ] ) ) {
1821
1822			// Do not traverse comment nodes
1823			ret += getText( node );
1824		}
1825	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1826
1827		// Use textContent for elements
1828		// innerText usage removed for consistency of new lines (jQuery #11153)
1829		if ( typeof elem.textContent === "string" ) {
1830			return elem.textContent;
1831		} else {
1832
1833			// Traverse its children
1834			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1835				ret += getText( elem );
1836			}
1837		}
1838	} else if ( nodeType === 3 || nodeType === 4 ) {
1839		return elem.nodeValue;
1840	}
1841
1842	// Do not include comment or processing instruction nodes
1843
1844	return ret;
1845};
1846
1847Expr = Sizzle.selectors = {
1848
1849	// Can be adjusted by the user
1850	cacheLength: 50,
1851
1852	createPseudo: markFunction,
1853
1854	match: matchExpr,
1855
1856	attrHandle: {},
1857
1858	find: {},
1859
1860	relative: {
1861		">": { dir: "parentNode", first: true },
1862		" ": { dir: "parentNode" },
1863		"+": { dir: "previousSibling", first: true },
1864		"~": { dir: "previousSibling" }
1865	},
1866
1867	preFilter: {
1868		"ATTR": function( match ) {
1869			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
1870
1871			// Move the given value to match[3] whether quoted or unquoted
1872			match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
1873				match[ 5 ] || "" ).replace( runescape, funescape );
1874
1875			if ( match[ 2 ] === "~=" ) {
1876				match[ 3 ] = " " + match[ 3 ] + " ";
1877			}
1878
1879			return match.slice( 0, 4 );
1880		},
1881
1882		"CHILD": function( match ) {
1883
1884			/* matches from matchExpr["CHILD"]
1885				1 type (only|nth|...)
1886				2 what (child|of-type)
1887				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1888				4 xn-component of xn+y argument ([+-]?\d*n|)
1889				5 sign of xn-component
1890				6 x of xn-component
1891				7 sign of y-component
1892				8 y of y-component
1893			*/
1894			match[ 1 ] = match[ 1 ].toLowerCase();
1895
1896			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
1897
1898				// nth-* requires argument
1899				if ( !match[ 3 ] ) {
1900					Sizzle.error( match[ 0 ] );
1901				}
1902
1903				// numeric x and y parameters for Expr.filter.CHILD
1904				// remember that false/true cast respectively to 0/1
1905				match[ 4 ] = +( match[ 4 ] ?
1906					match[ 5 ] + ( match[ 6 ] || 1 ) :
1907					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
1908				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
1909
1910				// other types prohibit arguments
1911			} else if ( match[ 3 ] ) {
1912				Sizzle.error( match[ 0 ] );
1913			}
1914
1915			return match;
1916		},
1917
1918		"PSEUDO": function( match ) {
1919			var excess,
1920				unquoted = !match[ 6 ] && match[ 2 ];
1921
1922			if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
1923				return null;
1924			}
1925
1926			// Accept quoted arguments as-is
1927			if ( match[ 3 ] ) {
1928				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
1929
1930			// Strip excess characters from unquoted arguments
1931			} else if ( unquoted && rpseudo.test( unquoted ) &&
1932
1933				// Get excess from tokenize (recursively)
1934				( excess = tokenize( unquoted, true ) ) &&
1935
1936				// advance to the next closing parenthesis
1937				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
1938
1939				// excess is a negative index
1940				match[ 0 ] = match[ 0 ].slice( 0, excess );
1941				match[ 2 ] = unquoted.slice( 0, excess );
1942			}
1943
1944			// Return only captures needed by the pseudo filter method (type and argument)
1945			return match.slice( 0, 3 );
1946		}
1947	},
1948
1949	filter: {
1950
1951		"TAG": function( nodeNameSelector ) {
1952			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1953			return nodeNameSelector === "*" ?
1954				function() {
1955					return true;
1956				} :
1957				function( elem ) {
1958					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1959				};
1960		},
1961
1962		"CLASS": function( className ) {
1963			var pattern = classCache[ className + " " ];
1964
1965			return pattern ||
1966				( pattern = new RegExp( "(^|" + whitespace +
1967					")" + className + "(" + whitespace + "|$)" ) ) && classCache(
1968						className, function( elem ) {
1969							return pattern.test(
1970								typeof elem.className === "string" && elem.className ||
1971								typeof elem.getAttribute !== "undefined" &&
1972									elem.getAttribute( "class" ) ||
1973								""
1974							);
1975				} );
1976		},
1977
1978		"ATTR": function( name, operator, check ) {
1979			return function( elem ) {
1980				var result = Sizzle.attr( elem, name );
1981
1982				if ( result == null ) {
1983					return operator === "!=";
1984				}
1985				if ( !operator ) {
1986					return true;
1987				}
1988
1989				result += "";
1990
1991				/* eslint-disable max-len */
1992
1993				return operator === "=" ? result === check :
1994					operator === "!=" ? result !== check :
1995					operator === "^=" ? check && result.indexOf( check ) === 0 :
1996					operator === "*=" ? check && result.indexOf( check ) > -1 :
1997					operator === "$=" ? check && result.slice( -check.length ) === check :
1998					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1999					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
2000					false;
2001				/* eslint-enable max-len */
2002
2003			};
2004		},
2005
2006		"CHILD": function( type, what, _argument, first, last ) {
2007			var simple = type.slice( 0, 3 ) !== "nth",
2008				forward = type.slice( -4 ) !== "last",
2009				ofType = what === "of-type";
2010
2011			return first === 1 && last === 0 ?
2012
2013				// Shortcut for :nth-*(n)
2014				function( elem ) {
2015					return !!elem.parentNode;
2016				} :
2017
2018				function( elem, _context, xml ) {
2019					var cache, uniqueCache, outerCache, node, nodeIndex, start,
2020						dir = simple !== forward ? "nextSibling" : "previousSibling",
2021						parent = elem.parentNode,
2022						name = ofType && elem.nodeName.toLowerCase(),
2023						useCache = !xml && !ofType,
2024						diff = false;
2025
2026					if ( parent ) {
2027
2028						// :(first|last|only)-(child|of-type)
2029						if ( simple ) {
2030							while ( dir ) {
2031								node = elem;
2032								while ( ( node = node[ dir ] ) ) {
2033									if ( ofType ?
2034										node.nodeName.toLowerCase() === name :
2035										node.nodeType === 1 ) {
2036
2037										return false;
2038									}
2039								}
2040
2041								// Reverse direction for :only-* (if we haven't yet done so)
2042								start = dir = type === "only" && !start && "nextSibling";
2043							}
2044							return true;
2045						}
2046
2047						start = [ forward ? parent.firstChild : parent.lastChild ];
2048
2049						// non-xml :nth-child(...) stores cache data on `parent`
2050						if ( forward && useCache ) {
2051
2052							// Seek `elem` from a previously-cached index
2053
2054							// ...in a gzip-friendly way
2055							node = parent;
2056							outerCache = node[ expando ] || ( node[ expando ] = {} );
2057
2058							// Support: IE <9 only
2059							// Defend against cloned attroperties (jQuery gh-1709)
2060							uniqueCache = outerCache[ node.uniqueID ] ||
2061								( outerCache[ node.uniqueID ] = {} );
2062
2063							cache = uniqueCache[ type ] || [];
2064							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2065							diff = nodeIndex && cache[ 2 ];
2066							node = nodeIndex && parent.childNodes[ nodeIndex ];
2067
2068							while ( ( node = ++nodeIndex && node && node[ dir ] ||
2069
2070								// Fallback to seeking `elem` from the start
2071								( diff = nodeIndex = 0 ) || start.pop() ) ) {
2072
2073								// When found, cache indexes on `parent` and break
2074								if ( node.nodeType === 1 && ++diff && node === elem ) {
2075									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
2076									break;
2077								}
2078							}
2079
2080						} else {
2081
2082							// Use previously-cached element index if available
2083							if ( useCache ) {
2084
2085								// ...in a gzip-friendly way
2086								node = elem;
2087								outerCache = node[ expando ] || ( node[ expando ] = {} );
2088
2089								// Support: IE <9 only
2090								// Defend against cloned attroperties (jQuery gh-1709)
2091								uniqueCache = outerCache[ node.uniqueID ] ||
2092									( outerCache[ node.uniqueID ] = {} );
2093
2094								cache = uniqueCache[ type ] || [];
2095								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2096								diff = nodeIndex;
2097							}
2098
2099							// xml :nth-child(...)
2100							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
2101							if ( diff === false ) {
2102
2103								// Use the same loop as above to seek `elem` from the start
2104								while ( ( node = ++nodeIndex && node && node[ dir ] ||
2105									( diff = nodeIndex = 0 ) || start.pop() ) ) {
2106
2107									if ( ( ofType ?
2108										node.nodeName.toLowerCase() === name :
2109										node.nodeType === 1 ) &&
2110										++diff ) {
2111
2112										// Cache the index of each encountered element
2113										if ( useCache ) {
2114											outerCache = node[ expando ] ||
2115												( node[ expando ] = {} );
2116
2117											// Support: IE <9 only
2118											// Defend against cloned attroperties (jQuery gh-1709)
2119											uniqueCache = outerCache[ node.uniqueID ] ||
2120												( outerCache[ node.uniqueID ] = {} );
2121
2122											uniqueCache[ type ] = [ dirruns, diff ];
2123										}
2124
2125										if ( node === elem ) {
2126											break;
2127										}
2128									}
2129								}
2130							}
2131						}
2132
2133						// Incorporate the offset, then check against cycle size
2134						diff -= last;
2135						return diff === first || ( diff % first === 0 && diff / first >= 0 );
2136					}
2137				};
2138		},
2139
2140		"PSEUDO": function( pseudo, argument ) {
2141
2142			// pseudo-class names are case-insensitive
2143			// http://www.w3.org/TR/selectors/#pseudo-classes
2144			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2145			// Remember that setFilters inherits from pseudos
2146			var args,
2147				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2148					Sizzle.error( "unsupported pseudo: " + pseudo );
2149
2150			// The user may use createPseudo to indicate that
2151			// arguments are needed to create the filter function
2152			// just as Sizzle does
2153			if ( fn[ expando ] ) {
2154				return fn( argument );
2155			}
2156
2157			// But maintain support for old signatures
2158			if ( fn.length > 1 ) {
2159				args = [ pseudo, pseudo, "", argument ];
2160				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2161					markFunction( function( seed, matches ) {
2162						var idx,
2163							matched = fn( seed, argument ),
2164							i = matched.length;
2165						while ( i-- ) {
2166							idx = indexOf( seed, matched[ i ] );
2167							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
2168						}
2169					} ) :
2170					function( elem ) {
2171						return fn( elem, 0, args );
2172					};
2173			}
2174
2175			return fn;
2176		}
2177	},
2178
2179	pseudos: {
2180
2181		// Potentially complex pseudos
2182		"not": markFunction( function( selector ) {
2183
2184			// Trim the selector passed to compile
2185			// to avoid treating leading and trailing
2186			// spaces as combinators
2187			var input = [],
2188				results = [],
2189				matcher = compile( selector.replace( rtrim, "$1" ) );
2190
2191			return matcher[ expando ] ?
2192				markFunction( function( seed, matches, _context, xml ) {
2193					var elem,
2194						unmatched = matcher( seed, null, xml, [] ),
2195						i = seed.length;
2196
2197					// Match elements unmatched by `matcher`
2198					while ( i-- ) {
2199						if ( ( elem = unmatched[ i ] ) ) {
2200							seed[ i ] = !( matches[ i ] = elem );
2201						}
2202					}
2203				} ) :
2204				function( elem, _context, xml ) {
2205					input[ 0 ] = elem;
2206					matcher( input, null, xml, results );
2207
2208					// Don't keep the element (issue #299)
2209					input[ 0 ] = null;
2210					return !results.pop();
2211				};
2212		} ),
2213
2214		"has": markFunction( function( selector ) {
2215			return function( elem ) {
2216				return Sizzle( selector, elem ).length > 0;
2217			};
2218		} ),
2219
2220		"contains": markFunction( function( text ) {
2221			text = text.replace( runescape, funescape );
2222			return function( elem ) {
2223				return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
2224			};
2225		} ),
2226
2227		// "Whether an element is represented by a :lang() selector
2228		// is based solely on the element's language value
2229		// being equal to the identifier C,
2230		// or beginning with the identifier C immediately followed by "-".
2231		// The matching of C against the element's language value is performed case-insensitively.
2232		// The identifier C does not have to be a valid language name."
2233		// http://www.w3.org/TR/selectors/#lang-pseudo
2234		"lang": markFunction( function( lang ) {
2235
2236			// lang value must be a valid identifier
2237			if ( !ridentifier.test( lang || "" ) ) {
2238				Sizzle.error( "unsupported lang: " + lang );
2239			}
2240			lang = lang.replace( runescape, funescape ).toLowerCase();
2241			return function( elem ) {
2242				var elemLang;
2243				do {
2244					if ( ( elemLang = documentIsHTML ?
2245						elem.lang :
2246						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
2247
2248						elemLang = elemLang.toLowerCase();
2249						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2250					}
2251				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
2252				return false;
2253			};
2254		} ),
2255
2256		// Miscellaneous
2257		"target": function( elem ) {
2258			var hash = window.location && window.location.hash;
2259			return hash && hash.slice( 1 ) === elem.id;
2260		},
2261
2262		"root": function( elem ) {
2263			return elem === docElem;
2264		},
2265
2266		"focus": function( elem ) {
2267			return elem === document.activeElement &&
2268				( !document.hasFocus || document.hasFocus() ) &&
2269				!!( elem.type || elem.href || ~elem.tabIndex );
2270		},
2271
2272		// Boolean properties
2273		"enabled": createDisabledPseudo( false ),
2274		"disabled": createDisabledPseudo( true ),
2275
2276		"checked": function( elem ) {
2277
2278			// In CSS3, :checked should return both checked and selected elements
2279			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2280			var nodeName = elem.nodeName.toLowerCase();
2281			return ( nodeName === "input" && !!elem.checked ) ||
2282				( nodeName === "option" && !!elem.selected );
2283		},
2284
2285		"selected": function( elem ) {
2286
2287			// Accessing this property makes selected-by-default
2288			// options in Safari work properly
2289			if ( elem.parentNode ) {
2290				// eslint-disable-next-line no-unused-expressions
2291				elem.parentNode.selectedIndex;
2292			}
2293
2294			return elem.selected === true;
2295		},
2296
2297		// Contents
2298		"empty": function( elem ) {
2299
2300			// http://www.w3.org/TR/selectors/#empty-pseudo
2301			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2302			//   but not by others (comment: 8; processing instruction: 7; etc.)
2303			// nodeType < 6 works because attributes (2) do not appear as children
2304			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2305				if ( elem.nodeType < 6 ) {
2306					return false;
2307				}
2308			}
2309			return true;
2310		},
2311
2312		"parent": function( elem ) {
2313			return !Expr.pseudos[ "empty" ]( elem );
2314		},
2315
2316		// Element/input types
2317		"header": function( elem ) {
2318			return rheader.test( elem.nodeName );
2319		},
2320
2321		"input": function( elem ) {
2322			return rinputs.test( elem.nodeName );
2323		},
2324
2325		"button": function( elem ) {
2326			var name = elem.nodeName.toLowerCase();
2327			return name === "input" && elem.type === "button" || name === "button";
2328		},
2329
2330		"text": function( elem ) {
2331			var attr;
2332			return elem.nodeName.toLowerCase() === "input" &&
2333				elem.type === "text" &&
2334
2335				// Support: IE<8
2336				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2337				( ( attr = elem.getAttribute( "type" ) ) == null ||
2338					attr.toLowerCase() === "text" );
2339		},
2340
2341		// Position-in-collection
2342		"first": createPositionalPseudo( function() {
2343			return [ 0 ];
2344		} ),
2345
2346		"last": createPositionalPseudo( function( _matchIndexes, length ) {
2347			return [ length - 1 ];
2348		} ),
2349
2350		"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
2351			return [ argument < 0 ? argument + length : argument ];
2352		} ),
2353
2354		"even": createPositionalPseudo( function( matchIndexes, length ) {
2355			var i = 0;
2356			for ( ; i < length; i += 2 ) {
2357				matchIndexes.push( i );
2358			}
2359			return matchIndexes;
2360		} ),
2361
2362		"odd": createPositionalPseudo( function( matchIndexes, length ) {
2363			var i = 1;
2364			for ( ; i < length; i += 2 ) {
2365				matchIndexes.push( i );
2366			}
2367			return matchIndexes;
2368		} ),
2369
2370		"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2371			var i = argument < 0 ?
2372				argument + length :
2373				argument > length ?
2374					length :
2375					argument;
2376			for ( ; --i >= 0; ) {
2377				matchIndexes.push( i );
2378			}
2379			return matchIndexes;
2380		} ),
2381
2382		"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2383			var i = argument < 0 ? argument + length : argument;
2384			for ( ; ++i < length; ) {
2385				matchIndexes.push( i );
2386			}
2387			return matchIndexes;
2388		} )
2389	}
2390};
2391
2392Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
2393
2394// Add button/input type pseudos
2395for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2396	Expr.pseudos[ i ] = createInputPseudo( i );
2397}
2398for ( i in { submit: true, reset: true } ) {
2399	Expr.pseudos[ i ] = createButtonPseudo( i );
2400}
2401
2402// Easy API for creating new setFilters
2403function setFilters() {}
2404setFilters.prototype = Expr.filters = Expr.pseudos;
2405Expr.setFilters = new setFilters();
2406
2407tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2408	var matched, match, tokens, type,
2409		soFar, groups, preFilters,
2410		cached = tokenCache[ selector + " " ];
2411
2412	if ( cached ) {
2413		return parseOnly ? 0 : cached.slice( 0 );
2414	}
2415
2416	soFar = selector;
2417	groups = [];
2418	preFilters = Expr.preFilter;
2419
2420	while ( soFar ) {
2421
2422		// Comma and first run
2423		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
2424			if ( match ) {
2425
2426				// Don't consume trailing commas as valid
2427				soFar = soFar.slice( match[ 0 ].length ) || soFar;
2428			}
2429			groups.push( ( tokens = [] ) );
2430		}
2431
2432		matched = false;
2433
2434		// Combinators
2435		if ( ( match = rcombinators.exec( soFar ) ) ) {
2436			matched = match.shift();
2437			tokens.push( {
2438				value: matched,
2439
2440				// Cast descendant combinators to space
2441				type: match[ 0 ].replace( rtrim, " " )
2442			} );
2443			soFar = soFar.slice( matched.length );
2444		}
2445
2446		// Filters
2447		for ( type in Expr.filter ) {
2448			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
2449				( match = preFilters[ type ]( match ) ) ) ) {
2450				matched = match.shift();
2451				tokens.push( {
2452					value: matched,
2453					type: type,
2454					matches: match
2455				} );
2456				soFar = soFar.slice( matched.length );
2457			}
2458		}
2459
2460		if ( !matched ) {
2461			break;
2462		}
2463	}
2464
2465	// Return the length of the invalid excess
2466	// if we're just parsing
2467	// Otherwise, throw an error or return tokens
2468	return parseOnly ?
2469		soFar.length :
2470		soFar ?
2471			Sizzle.error( selector ) :
2472
2473			// Cache the tokens
2474			tokenCache( selector, groups ).slice( 0 );
2475};
2476
2477function toSelector( tokens ) {
2478	var i = 0,
2479		len = tokens.length,
2480		selector = "";
2481	for ( ; i < len; i++ ) {
2482		selector += tokens[ i ].value;
2483	}
2484	return selector;
2485}
2486
2487function addCombinator( matcher, combinator, base ) {
2488	var dir = combinator.dir,
2489		skip = combinator.next,
2490		key = skip || dir,
2491		checkNonElements = base && key === "parentNode",
2492		doneName = done++;
2493
2494	return combinator.first ?
2495
2496		// Check against closest ancestor/preceding element
2497		function( elem, context, xml ) {
2498			while ( ( elem = elem[ dir ] ) ) {
2499				if ( elem.nodeType === 1 || checkNonElements ) {
2500					return matcher( elem, context, xml );
2501				}
2502			}
2503			return false;
2504		} :
2505
2506		// Check against all ancestor/preceding elements
2507		function( elem, context, xml ) {
2508			var oldCache, uniqueCache, outerCache,
2509				newCache = [ dirruns, doneName ];
2510
2511			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2512			if ( xml ) {
2513				while ( ( elem = elem[ dir ] ) ) {
2514					if ( elem.nodeType === 1 || checkNonElements ) {
2515						if ( matcher( elem, context, xml ) ) {
2516							return true;
2517						}
2518					}
2519				}
2520			} else {
2521				while ( ( elem = elem[ dir ] ) ) {
2522					if ( elem.nodeType === 1 || checkNonElements ) {
2523						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
2524
2525						// Support: IE <9 only
2526						// Defend against cloned attroperties (jQuery gh-1709)
2527						uniqueCache = outerCache[ elem.uniqueID ] ||
2528							( outerCache[ elem.uniqueID ] = {} );
2529
2530						if ( skip && skip === elem.nodeName.toLowerCase() ) {
2531							elem = elem[ dir ] || elem;
2532						} else if ( ( oldCache = uniqueCache[ key ] ) &&
2533							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2534
2535							// Assign to newCache so results back-propagate to previous elements
2536							return ( newCache[ 2 ] = oldCache[ 2 ] );
2537						} else {
2538
2539							// Reuse newcache so results back-propagate to previous elements
2540							uniqueCache[ key ] = newCache;
2541
2542							// A match means we're done; a fail means we have to keep checking
2543							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
2544								return true;
2545							}
2546						}
2547					}
2548				}
2549			}
2550			return false;
2551		};
2552}
2553
2554function elementMatcher( matchers ) {
2555	return matchers.length > 1 ?
2556		function( elem, context, xml ) {
2557			var i = matchers.length;
2558			while ( i-- ) {
2559				if ( !matchers[ i ]( elem, context, xml ) ) {
2560					return false;
2561				}
2562			}
2563			return true;
2564		} :
2565		matchers[ 0 ];
2566}
2567
2568function multipleContexts( selector, contexts, results ) {
2569	var i = 0,
2570		len = contexts.length;
2571	for ( ; i < len; i++ ) {
2572		Sizzle( selector, contexts[ i ], results );
2573	}
2574	return results;
2575}
2576
2577function condense( unmatched, map, filter, context, xml ) {
2578	var elem,
2579		newUnmatched = [],
2580		i = 0,
2581		len = unmatched.length,
2582		mapped = map != null;
2583
2584	for ( ; i < len; i++ ) {
2585		if ( ( elem = unmatched[ i ] ) ) {
2586			if ( !filter || filter( elem, context, xml ) ) {
2587				newUnmatched.push( elem );
2588				if ( mapped ) {
2589					map.push( i );
2590				}
2591			}
2592		}
2593	}
2594
2595	return newUnmatched;
2596}
2597
2598function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2599	if ( postFilter && !postFilter[ expando ] ) {
2600		postFilter = setMatcher( postFilter );
2601	}
2602	if ( postFinder && !postFinder[ expando ] ) {
2603		postFinder = setMatcher( postFinder, postSelector );
2604	}
2605	return markFunction( function( seed, results, context, xml ) {
2606		var temp, i, elem,
2607			preMap = [],
2608			postMap = [],
2609			preexisting = results.length,
2610
2611			// Get initial elements from seed or context
2612			elems = seed || multipleContexts(
2613				selector || "*",
2614				context.nodeType ? [ context ] : context,
2615				[]
2616			),
2617
2618			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2619			matcherIn = preFilter && ( seed || !selector ) ?
2620				condense( elems, preMap, preFilter, context, xml ) :
2621				elems,
2622
2623			matcherOut = matcher ?
2624
2625				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2626				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2627
2628					// ...intermediate processing is necessary
2629					[] :
2630
2631					// ...otherwise use results directly
2632					results :
2633				matcherIn;
2634
2635		// Find primary matches
2636		if ( matcher ) {
2637			matcher( matcherIn, matcherOut, context, xml );
2638		}
2639
2640		// Apply postFilter
2641		if ( postFilter ) {
2642			temp = condense( matcherOut, postMap );
2643			postFilter( temp, [], context, xml );
2644
2645			// Un-match failing elements by moving them back to matcherIn
2646			i = temp.length;
2647			while ( i-- ) {
2648				if ( ( elem = temp[ i ] ) ) {
2649					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
2650				}
2651			}
2652		}
2653
2654		if ( seed ) {
2655			if ( postFinder || preFilter ) {
2656				if ( postFinder ) {
2657
2658					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2659					temp = [];
2660					i = matcherOut.length;
2661					while ( i-- ) {
2662						if ( ( elem = matcherOut[ i ] ) ) {
2663
2664							// Restore matcherIn since elem is not yet a final match
2665							temp.push( ( matcherIn[ i ] = elem ) );
2666						}
2667					}
2668					postFinder( null, ( matcherOut = [] ), temp, xml );
2669				}
2670
2671				// Move matched elements from seed to results to keep them synchronized
2672				i = matcherOut.length;
2673				while ( i-- ) {
2674					if ( ( elem = matcherOut[ i ] ) &&
2675						( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
2676
2677						seed[ temp ] = !( results[ temp ] = elem );
2678					}
2679				}
2680			}
2681
2682		// Add elements to results, through postFinder if defined
2683		} else {
2684			matcherOut = condense(
2685				matcherOut === results ?
2686					matcherOut.splice( preexisting, matcherOut.length ) :
2687					matcherOut
2688			);
2689			if ( postFinder ) {
2690				postFinder( null, results, matcherOut, xml );
2691			} else {
2692				push.apply( results, matcherOut );
2693			}
2694		}
2695	} );
2696}
2697
2698function matcherFromTokens( tokens ) {
2699	var checkContext, matcher, j,
2700		len = tokens.length,
2701		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
2702		implicitRelative = leadingRelative || Expr.relative[ " " ],
2703		i = leadingRelative ? 1 : 0,
2704
2705		// The foundational matcher ensures that elements are reachable from top-level context(s)
2706		matchContext = addCombinator( function( elem ) {
2707			return elem === checkContext;
2708		}, implicitRelative, true ),
2709		matchAnyContext = addCombinator( function( elem ) {
2710			return indexOf( checkContext, elem ) > -1;
2711		}, implicitRelative, true ),
2712		matchers = [ function( elem, context, xml ) {
2713			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2714				( checkContext = context ).nodeType ?
2715					matchContext( elem, context, xml ) :
2716					matchAnyContext( elem, context, xml ) );
2717
2718			// Avoid hanging onto element (issue #299)
2719			checkContext = null;
2720			return ret;
2721		} ];
2722
2723	for ( ; i < len; i++ ) {
2724		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
2725			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
2726		} else {
2727			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
2728
2729			// Return special upon seeing a positional matcher
2730			if ( matcher[ expando ] ) {
2731
2732				// Find the next relative operator (if any) for proper handling
2733				j = ++i;
2734				for ( ; j < len; j++ ) {
2735					if ( Expr.relative[ tokens[ j ].type ] ) {
2736						break;
2737					}
2738				}
2739				return setMatcher(
2740					i > 1 && elementMatcher( matchers ),
2741					i > 1 && toSelector(
2742
2743					// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2744					tokens
2745						.slice( 0, i - 1 )
2746						.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
2747					).replace( rtrim, "$1" ),
2748					matcher,
2749					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2750					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
2751					j < len && toSelector( tokens )
2752				);
2753			}
2754			matchers.push( matcher );
2755		}
2756	}
2757
2758	return elementMatcher( matchers );
2759}
2760
2761function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2762	var bySet = setMatchers.length > 0,
2763		byElement = elementMatchers.length > 0,
2764		superMatcher = function( seed, context, xml, results, outermost ) {
2765			var elem, j, matcher,
2766				matchedCount = 0,
2767				i = "0",
2768				unmatched = seed && [],
2769				setMatched = [],
2770				contextBackup = outermostContext,
2771
2772				// We must always have either seed elements or outermost context
2773				elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
2774
2775				// Use integer dirruns iff this is the outermost matcher
2776				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
2777				len = elems.length;
2778
2779			if ( outermost ) {
2780
2781				// Support: IE 11+, Edge 17 - 18+
2782				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2783				// two documents; shallow comparisons work.
2784				// eslint-disable-next-line eqeqeq
2785				outermostContext = context == document || context || outermost;
2786			}
2787
2788			// Add elements passing elementMatchers directly to results
2789			// Support: IE<9, Safari
2790			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2791			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
2792				if ( byElement && elem ) {
2793					j = 0;
2794
2795					// Support: IE 11+, Edge 17 - 18+
2796					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2797					// two documents; shallow comparisons work.
2798					// eslint-disable-next-line eqeqeq
2799					if ( !context && elem.ownerDocument != document ) {
2800						setDocument( elem );
2801						xml = !documentIsHTML;
2802					}
2803					while ( ( matcher = elementMatchers[ j++ ] ) ) {
2804						if ( matcher( elem, context || document, xml ) ) {
2805							results.push( elem );
2806							break;
2807						}
2808					}
2809					if ( outermost ) {
2810						dirruns = dirrunsUnique;
2811					}
2812				}
2813
2814				// Track unmatched elements for set filters
2815				if ( bySet ) {
2816
2817					// They will have gone through all possible matchers
2818					if ( ( elem = !matcher && elem ) ) {
2819						matchedCount--;
2820					}
2821
2822					// Lengthen the array for every element, matched or not
2823					if ( seed ) {
2824						unmatched.push( elem );
2825					}
2826				}
2827			}
2828
2829			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2830			// makes the latter nonnegative.
2831			matchedCount += i;
2832
2833			// Apply set filters to unmatched elements
2834			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2835			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2836			// no element matchers and no seed.
2837			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2838			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2839			// numerically zero.
2840			if ( bySet && i !== matchedCount ) {
2841				j = 0;
2842				while ( ( matcher = setMatchers[ j++ ] ) ) {
2843					matcher( unmatched, setMatched, context, xml );
2844				}
2845
2846				if ( seed ) {
2847
2848					// Reintegrate element matches to eliminate the need for sorting
2849					if ( matchedCount > 0 ) {
2850						while ( i-- ) {
2851							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
2852								setMatched[ i ] = pop.call( results );
2853							}
2854						}
2855					}
2856
2857					// Discard index placeholder values to get only actual matches
2858					setMatched = condense( setMatched );
2859				}
2860
2861				// Add matches to results
2862				push.apply( results, setMatched );
2863
2864				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2865				if ( outermost && !seed && setMatched.length > 0 &&
2866					( matchedCount + setMatchers.length ) > 1 ) {
2867
2868					Sizzle.uniqueSort( results );
2869				}
2870			}
2871
2872			// Override manipulation of globals by nested matchers
2873			if ( outermost ) {
2874				dirruns = dirrunsUnique;
2875				outermostContext = contextBackup;
2876			}
2877
2878			return unmatched;
2879		};
2880
2881	return bySet ?
2882		markFunction( superMatcher ) :
2883		superMatcher;
2884}
2885
2886compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2887	var i,
2888		setMatchers = [],
2889		elementMatchers = [],
2890		cached = compilerCache[ selector + " " ];
2891
2892	if ( !cached ) {
2893
2894		// Generate a function of recursive functions that can be used to check each element
2895		if ( !match ) {
2896			match = tokenize( selector );
2897		}
2898		i = match.length;
2899		while ( i-- ) {
2900			cached = matcherFromTokens( match[ i ] );
2901			if ( cached[ expando ] ) {
2902				setMatchers.push( cached );
2903			} else {
2904				elementMatchers.push( cached );
2905			}
2906		}
2907
2908		// Cache the compiled function
2909		cached = compilerCache(
2910			selector,
2911			matcherFromGroupMatchers( elementMatchers, setMatchers )
2912		);
2913
2914		// Save selector and tokenization
2915		cached.selector = selector;
2916	}
2917	return cached;
2918};
2919
2920/**
2921 * A low-level selection function that works with Sizzle's compiled
2922 *  selector functions
2923 * @param {String|Function} selector A selector or a pre-compiled
2924 *  selector function built with Sizzle.compile
2925 * @param {Element} context
2926 * @param {Array} [results]
2927 * @param {Array} [seed] A set of elements to match against
2928 */
2929select = Sizzle.select = function( selector, context, results, seed ) {
2930	var i, tokens, token, type, find,
2931		compiled = typeof selector === "function" && selector,
2932		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
2933
2934	results = results || [];
2935
2936	// Try to minimize operations if there is only one selector in the list and no seed
2937	// (the latter of which guarantees us context)
2938	if ( match.length === 1 ) {
2939
2940		// Reduce context if the leading compound selector is an ID
2941		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
2942		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
2943			context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
2944
2945			context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
2946				.replace( runescape, funescape ), context ) || [] )[ 0 ];
2947			if ( !context ) {
2948				return results;
2949
2950			// Precompiled matchers will still verify ancestry, so step up a level
2951			} else if ( compiled ) {
2952				context = context.parentNode;
2953			}
2954
2955			selector = selector.slice( tokens.shift().value.length );
2956		}
2957
2958		// Fetch a seed set for right-to-left matching
2959		i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
2960		while ( i-- ) {
2961			token = tokens[ i ];
2962
2963			// Abort if we hit a combinator
2964			if ( Expr.relative[ ( type = token.type ) ] ) {
2965				break;
2966			}
2967			if ( ( find = Expr.find[ type ] ) ) {
2968
2969				// Search, expanding context for leading sibling combinators
2970				if ( ( seed = find(
2971					token.matches[ 0 ].replace( runescape, funescape ),
2972					rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
2973						context
2974				) ) ) {
2975
2976					// If seed is empty or no tokens remain, we can return early
2977					tokens.splice( i, 1 );
2978					selector = seed.length && toSelector( tokens );
2979					if ( !selector ) {
2980						push.apply( results, seed );
2981						return results;
2982					}
2983
2984					break;
2985				}
2986			}
2987		}
2988	}
2989
2990	// Compile and execute a filtering function if one is not provided
2991	// Provide `match` to avoid retokenization if we modified the selector above
2992	( compiled || compile( selector, match ) )(
2993		seed,
2994		context,
2995		!documentIsHTML,
2996		results,
2997		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2998	);
2999	return results;
3000};
3001
3002// One-time assignments
3003
3004// Sort stability
3005support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
3006
3007// Support: Chrome 14-35+
3008// Always assume duplicates if they aren't passed to the comparison function
3009support.detectDuplicates = !!hasDuplicate;
3010
3011// Initialize against the default document
3012setDocument();
3013
3014// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
3015// Detached nodes confoundingly follow *each other*
3016support.sortDetached = assert( function( el ) {
3017
3018	// Should return 1, but returns 4 (following)
3019	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
3020} );
3021
3022// Support: IE<8
3023// Prevent attribute/property "interpolation"
3024// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
3025if ( !assert( function( el ) {
3026	el.innerHTML = "<a href='#'></a>";
3027	return el.firstChild.getAttribute( "href" ) === "#";
3028} ) ) {
3029	addHandle( "type|href|height|width", function( elem, name, isXML ) {
3030		if ( !isXML ) {
3031			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
3032		}
3033	} );
3034}
3035
3036// Support: IE<9
3037// Use defaultValue in place of getAttribute("value")
3038if ( !support.attributes || !assert( function( el ) {
3039	el.innerHTML = "<input/>";
3040	el.firstChild.setAttribute( "value", "" );
3041	return el.firstChild.getAttribute( "value" ) === "";
3042} ) ) {
3043	addHandle( "value", function( elem, _name, isXML ) {
3044		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
3045			return elem.defaultValue;
3046		}
3047	} );
3048}
3049
3050// Support: IE<9
3051// Use getAttributeNode to fetch booleans when getAttribute lies
3052if ( !assert( function( el ) {
3053	return el.getAttribute( "disabled" ) == null;
3054} ) ) {
3055	addHandle( booleans, function( elem, name, isXML ) {
3056		var val;
3057		if ( !isXML ) {
3058			return elem[ name ] === true ? name.toLowerCase() :
3059				( val = elem.getAttributeNode( name ) ) && val.specified ?
3060					val.value :
3061					null;
3062		}
3063	} );
3064}
3065
3066return Sizzle;
3067
3068} )( window );
3069
3070
3071
3072jQuery.find = Sizzle;
3073jQuery.expr = Sizzle.selectors;
3074
3075// Deprecated
3076jQuery.expr[ ":" ] = jQuery.expr.pseudos;
3077jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
3078jQuery.text = Sizzle.getText;
3079jQuery.isXMLDoc = Sizzle.isXML;
3080jQuery.contains = Sizzle.contains;
3081jQuery.escapeSelector = Sizzle.escape;
3082
3083
3084
3085
3086var dir = function( elem, dir, until ) {
3087	var matched = [],
3088		truncate = until !== undefined;
3089
3090	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
3091		if ( elem.nodeType === 1 ) {
3092			if ( truncate && jQuery( elem ).is( until ) ) {
3093				break;
3094			}
3095			matched.push( elem );
3096		}
3097	}
3098	return matched;
3099};
3100
3101
3102var siblings = function( n, elem ) {
3103	var matched = [];
3104
3105	for ( ; n; n = n.nextSibling ) {
3106		if ( n.nodeType === 1 && n !== elem ) {
3107			matched.push( n );
3108		}
3109	}
3110
3111	return matched;
3112};
3113
3114
3115var rneedsContext = jQuery.expr.match.needsContext;
3116
3117
3118
3119function nodeName( elem, name ) {
3120
3121	return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
3122
3123}
3124var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
3125
3126
3127
3128// Implement the identical functionality for filter and not
3129function winnow( elements, qualifier, not ) {
3130	if ( isFunction( qualifier ) ) {
3131		return jQuery.grep( elements, function( elem, i ) {
3132			return !!qualifier.call( elem, i, elem ) !== not;
3133		} );
3134	}
3135
3136	// Single element
3137	if ( qualifier.nodeType ) {
3138		return jQuery.grep( elements, function( elem ) {
3139			return ( elem === qualifier ) !== not;
3140		} );
3141	}
3142
3143	// Arraylike of elements (jQuery, arguments, Array)
3144	if ( typeof qualifier !== "string" ) {
3145		return jQuery.grep( elements, function( elem ) {
3146			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3147		} );
3148	}
3149
3150	// Filtered directly for both simple and complex selectors
3151	return jQuery.filter( qualifier, elements, not );
3152}
3153
3154jQuery.filter = function( expr, elems, not ) {
3155	var elem = elems[ 0 ];
3156
3157	if ( not ) {
3158		expr = ":not(" + expr + ")";
3159	}
3160
3161	if ( elems.length === 1 && elem.nodeType === 1 ) {
3162		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
3163	}
3164
3165	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3166		return elem.nodeType === 1;
3167	} ) );
3168};
3169
3170jQuery.fn.extend( {
3171	find: function( selector ) {
3172		var i, ret,
3173			len = this.length,
3174			self = this;
3175
3176		if ( typeof selector !== "string" ) {
3177			return this.pushStack( jQuery( selector ).filter( function() {
3178				for ( i = 0; i < len; i++ ) {
3179					if ( jQuery.contains( self[ i ], this ) ) {
3180						return true;
3181					}
3182				}
3183			} ) );
3184		}
3185
3186		ret = this.pushStack( [] );
3187
3188		for ( i = 0; i < len; i++ ) {
3189			jQuery.find( selector, self[ i ], ret );
3190		}
3191
3192		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
3193	},
3194	filter: function( selector ) {
3195		return this.pushStack( winnow( this, selector || [], false ) );
3196	},
3197	not: function( selector ) {
3198		return this.pushStack( winnow( this, selector || [], true ) );
3199	},
3200	is: function( selector ) {
3201		return !!winnow(
3202			this,
3203
3204			// If this is a positional/relative selector, check membership in the returned set
3205			// so $("p:first").is("p:last") won't return true for a doc with two "p".
3206			typeof selector === "string" && rneedsContext.test( selector ) ?
3207				jQuery( selector ) :
3208				selector || [],
3209			false
3210		).length;
3211	}
3212} );
3213
3214
3215// Initialize a jQuery object
3216
3217
3218// A central reference to the root jQuery(document)
3219var rootjQuery,
3220
3221	// A simple way to check for HTML strings
3222	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
3223	// Strict HTML recognition (#11290: must start with <)
3224	// Shortcut simple #id case for speed
3225	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
3226
3227	init = jQuery.fn.init = function( selector, context, root ) {
3228		var match, elem;
3229
3230		// HANDLE: $(""), $(null), $(undefined), $(false)
3231		if ( !selector ) {
3232			return this;
3233		}
3234
3235		// Method init() accepts an alternate rootjQuery
3236		// so migrate can support jQuery.sub (gh-2101)
3237		root = root || rootjQuery;
3238
3239		// Handle HTML strings
3240		if ( typeof selector === "string" ) {
3241			if ( selector[ 0 ] === "<" &&
3242				selector[ selector.length - 1 ] === ">" &&
3243				selector.length >= 3 ) {
3244
3245				// Assume that strings that start and end with <> are HTML and skip the regex check
3246				match = [ null, selector, null ];
3247
3248			} else {
3249				match = rquickExpr.exec( selector );
3250			}
3251
3252			// Match html or make sure no context is specified for #id
3253			if ( match && ( match[ 1 ] || !context ) ) {
3254
3255				// HANDLE: $(html) -> $(array)
3256				if ( match[ 1 ] ) {
3257					context = context instanceof jQuery ? context[ 0 ] : context;
3258
3259					// Option to run scripts is true for back-compat
3260					// Intentionally let the error be thrown if parseHTML is not present
3261					jQuery.merge( this, jQuery.parseHTML(
3262						match[ 1 ],
3263						context && context.nodeType ? context.ownerDocument || context : document,
3264						true
3265					) );
3266
3267					// HANDLE: $(html, props)
3268					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3269						for ( match in context ) {
3270
3271							// Properties of context are called as methods if possible
3272							if ( isFunction( this[ match ] ) ) {
3273								this[ match ]( context[ match ] );
3274
3275							// ...and otherwise set as attributes
3276							} else {
3277								this.attr( match, context[ match ] );
3278							}
3279						}
3280					}
3281
3282					return this;
3283
3284				// HANDLE: $(#id)
3285				} else {
3286					elem = document.getElementById( match[ 2 ] );
3287
3288					if ( elem ) {
3289
3290						// Inject the element directly into the jQuery object
3291						this[ 0 ] = elem;
3292						this.length = 1;
3293					}
3294					return this;
3295				}
3296
3297			// HANDLE: $(expr, $(...))
3298			} else if ( !context || context.jquery ) {
3299				return ( context || root ).find( selector );
3300
3301			// HANDLE: $(expr, context)
3302			// (which is just equivalent to: $(context).find(expr)
3303			} else {
3304				return this.constructor( context ).find( selector );
3305			}
3306
3307		// HANDLE: $(DOMElement)
3308		} else if ( selector.nodeType ) {
3309			this[ 0 ] = selector;
3310			this.length = 1;
3311			return this;
3312
3313		// HANDLE: $(function)
3314		// Shortcut for document ready
3315		} else if ( isFunction( selector ) ) {
3316			return root.ready !== undefined ?
3317				root.ready( selector ) :
3318
3319				// Execute immediately if ready is not present
3320				selector( jQuery );
3321		}
3322
3323		return jQuery.makeArray( selector, this );
3324	};
3325
3326// Give the init function the jQuery prototype for later instantiation
3327init.prototype = jQuery.fn;
3328
3329// Initialize central reference
3330rootjQuery = jQuery( document );
3331
3332
3333var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3334
3335	// Methods guaranteed to produce a unique set when starting from a unique set
3336	guaranteedUnique = {
3337		children: true,
3338		contents: true,
3339		next: true,
3340		prev: true
3341	};
3342
3343jQuery.fn.extend( {
3344	has: function( target ) {
3345		var targets = jQuery( target, this ),
3346			l = targets.length;
3347
3348		return this.filter( function() {
3349			var i = 0;
3350			for ( ; i < l; i++ ) {
3351				if ( jQuery.contains( this, targets[ i ] ) ) {
3352					return true;
3353				}
3354			}
3355		} );
3356	},
3357
3358	closest: function( selectors, context ) {
3359		var cur,
3360			i = 0,
3361			l = this.length,
3362			matched = [],
3363			targets = typeof selectors !== "string" && jQuery( selectors );
3364
3365		// Positional selectors never match, since there's no _selection_ context
3366		if ( !rneedsContext.test( selectors ) ) {
3367			for ( ; i < l; i++ ) {
3368				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3369
3370					// Always skip document fragments
3371					if ( cur.nodeType < 11 && ( targets ?
3372						targets.index( cur ) > -1 :
3373
3374						// Don't pass non-elements to Sizzle
3375						cur.nodeType === 1 &&
3376							jQuery.find.matchesSelector( cur, selectors ) ) ) {
3377
3378						matched.push( cur );
3379						break;
3380					}
3381				}
3382			}
3383		}
3384
3385		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3386	},
3387
3388	// Determine the position of an element within the set
3389	index: function( elem ) {
3390
3391		// No argument, return index in parent
3392		if ( !elem ) {
3393			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3394		}
3395
3396		// Index in selector
3397		if ( typeof elem === "string" ) {
3398			return indexOf.call( jQuery( elem ), this[ 0 ] );
3399		}
3400
3401		// Locate the position of the desired element
3402		return indexOf.call( this,
3403
3404			// If it receives a jQuery object, the first element is used
3405			elem.jquery ? elem[ 0 ] : elem
3406		);
3407	},
3408
3409	add: function( selector, context ) {
3410		return this.pushStack(
3411			jQuery.uniqueSort(
3412				jQuery.merge( this.get(), jQuery( selector, context ) )
3413			)
3414		);
3415	},
3416
3417	addBack: function( selector ) {
3418		return this.add( selector == null ?
3419			this.prevObject : this.prevObject.filter( selector )
3420		);
3421	}
3422} );
3423
3424function sibling( cur, dir ) {
3425	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3426	return cur;
3427}
3428
3429jQuery.each( {
3430	parent: function( elem ) {
3431		var parent = elem.parentNode;
3432		return parent && parent.nodeType !== 11 ? parent : null;
3433	},
3434	parents: function( elem ) {
3435		return dir( elem, "parentNode" );
3436	},
3437	parentsUntil: function( elem, _i, until ) {
3438		return dir( elem, "parentNode", until );
3439	},
3440	next: function( elem ) {
3441		return sibling( elem, "nextSibling" );
3442	},
3443	prev: function( elem ) {
3444		return sibling( elem, "previousSibling" );
3445	},
3446	nextAll: function( elem ) {
3447		return dir( elem, "nextSibling" );
3448	},
3449	prevAll: function( elem ) {
3450		return dir( elem, "previousSibling" );
3451	},
3452	nextUntil: function( elem, _i, until ) {
3453		return dir( elem, "nextSibling", until );
3454	},
3455	prevUntil: function( elem, _i, until ) {
3456		return dir( elem, "previousSibling", until );
3457	},
3458	siblings: function( elem ) {
3459		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3460	},
3461	children: function( elem ) {
3462		return siblings( elem.firstChild );
3463	},
3464	contents: function( elem ) {
3465		if ( elem.contentDocument != null &&
3466
3467			// Support: IE 11+
3468			// <object> elements with no `data` attribute has an object
3469			// `contentDocument` with a `null` prototype.
3470			getProto( elem.contentDocument ) ) {
3471
3472			return elem.contentDocument;
3473		}
3474
3475		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3476		// Treat the template element as a regular one in browsers that
3477		// don't support it.
3478		if ( nodeName( elem, "template" ) ) {
3479			elem = elem.content || elem;
3480		}
3481
3482		return jQuery.merge( [], elem.childNodes );
3483	}
3484}, function( name, fn ) {
3485	jQuery.fn[ name ] = function( until, selector ) {
3486		var matched = jQuery.map( this, fn, until );
3487
3488		if ( name.slice( -5 ) !== "Until" ) {
3489			selector = until;
3490		}
3491
3492		if ( selector && typeof selector === "string" ) {
3493			matched = jQuery.filter( selector, matched );
3494		}
3495
3496		if ( this.length > 1 ) {
3497
3498			// Remove duplicates
3499			if ( !guaranteedUnique[ name ] ) {
3500				jQuery.uniqueSort( matched );
3501			}
3502
3503			// Reverse order for parents* and prev-derivatives
3504			if ( rparentsprev.test( name ) ) {
3505				matched.reverse();
3506			}
3507		}
3508
3509		return this.pushStack( matched );
3510	};
3511} );
3512var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3513
3514
3515
3516// Convert String-formatted options into Object-formatted ones
3517function createOptions( options ) {
3518	var object = {};
3519	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3520		object[ flag ] = true;
3521	} );
3522	return object;
3523}
3524
3525/*
3526 * Create a callback list using the following parameters:
3527 *
3528 *	options: an optional list of space-separated options that will change how
3529 *			the callback list behaves or a more traditional option object
3530 *
3531 * By default a callback list will act like an event callback list and can be
3532 * "fired" multiple times.
3533 *
3534 * Possible options:
3535 *
3536 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3537 *
3538 *	memory:			will keep track of previous values and will call any callback added
3539 *					after the list has been fired right away with the latest "memorized"
3540 *					values (like a Deferred)
3541 *
3542 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3543 *
3544 *	stopOnFalse:	interrupt callings when a callback returns false
3545 *
3546 */
3547jQuery.Callbacks = function( options ) {
3548
3549	// Convert options from String-formatted to Object-formatted if needed
3550	// (we check in cache first)
3551	options = typeof options === "string" ?
3552		createOptions( options ) :
3553		jQuery.extend( {}, options );
3554
3555	var // Flag to know if list is currently firing
3556		firing,
3557
3558		// Last fire value for non-forgettable lists
3559		memory,
3560
3561		// Flag to know if list was already fired
3562		fired,
3563
3564		// Flag to prevent firing
3565		locked,
3566
3567		// Actual callback list
3568		list = [],
3569
3570		// Queue of execution data for repeatable lists
3571		queue = [],
3572
3573		// Index of currently firing callback (modified by add/remove as needed)
3574		firingIndex = -1,
3575
3576		// Fire callbacks
3577		fire = function() {
3578
3579			// Enforce single-firing
3580			locked = locked || options.once;
3581
3582			// Execute callbacks for all pending executions,
3583			// respecting firingIndex overrides and runtime changes
3584			fired = firing = true;
3585			for ( ; queue.length; firingIndex = -1 ) {
3586				memory = queue.shift();
3587				while ( ++firingIndex < list.length ) {
3588
3589					// Run callback and check for early termination
3590					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3591						options.stopOnFalse ) {
3592
3593						// Jump to end and forget the data so .add doesn't re-fire
3594						firingIndex = list.length;
3595						memory = false;
3596					}
3597				}
3598			}
3599
3600			// Forget the data if we're done with it
3601			if ( !options.memory ) {
3602				memory = false;
3603			}
3604
3605			firing = false;
3606
3607			// Clean up if we're done firing for good
3608			if ( locked ) {
3609
3610				// Keep an empty list if we have data for future add calls
3611				if ( memory ) {
3612					list = [];
3613
3614				// Otherwise, this object is spent
3615				} else {
3616					list = "";
3617				}
3618			}
3619		},
3620
3621		// Actual Callbacks object
3622		self = {
3623
3624			// Add a callback or a collection of callbacks to the list
3625			add: function() {
3626				if ( list ) {
3627
3628					// If we have memory from a past run, we should fire after adding
3629					if ( memory && !firing ) {
3630						firingIndex = list.length - 1;
3631						queue.push( memory );
3632					}
3633
3634					( function add( args ) {
3635						jQuery.each( args, function( _, arg ) {
3636							if ( isFunction( arg ) ) {
3637								if ( !options.unique || !self.has( arg ) ) {
3638									list.push( arg );
3639								}
3640							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
3641
3642								// Inspect recursively
3643								add( arg );
3644							}
3645						} );
3646					} )( arguments );
3647
3648					if ( memory && !firing ) {
3649						fire();
3650					}
3651				}
3652				return this;
3653			},
3654
3655			// Remove a callback from the list
3656			remove: function() {
3657				jQuery.each( arguments, function( _, arg ) {
3658					var index;
3659					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3660						list.splice( index, 1 );
3661
3662						// Handle firing indexes
3663						if ( index <= firingIndex ) {
3664							firingIndex--;
3665						}
3666					}
3667				} );
3668				return this;
3669			},
3670
3671			// Check if a given callback is in the list.
3672			// If no argument is given, return whether or not list has callbacks attached.
3673			has: function( fn ) {
3674				return fn ?
3675					jQuery.inArray( fn, list ) > -1 :
3676					list.length > 0;
3677			},
3678
3679			// Remove all callbacks from the list
3680			empty: function() {
3681				if ( list ) {
3682					list = [];
3683				}
3684				return this;
3685			},
3686
3687			// Disable .fire and .add
3688			// Abort any current/pending executions
3689			// Clear all callbacks and values
3690			disable: function() {
3691				locked = queue = [];
3692				list = memory = "";
3693				return this;
3694			},
3695			disabled: function() {
3696				return !list;
3697			},
3698
3699			// Disable .fire
3700			// Also disable .add unless we have memory (since it would have no effect)
3701			// Abort any pending executions
3702			lock: function() {
3703				locked = queue = [];
3704				if ( !memory && !firing ) {
3705					list = memory = "";
3706				}
3707				return this;
3708			},
3709			locked: function() {
3710				return !!locked;
3711			},
3712
3713			// Call all callbacks with the given context and arguments
3714			fireWith: function( context, args ) {
3715				if ( !locked ) {
3716					args = args || [];
3717					args = [ context, args.slice ? args.slice() : args ];
3718					queue.push( args );
3719					if ( !firing ) {
3720						fire();
3721					}
3722				}
3723				return this;
3724			},
3725
3726			// Call all the callbacks with the given arguments
3727			fire: function() {
3728				self.fireWith( this, arguments );
3729				return this;
3730			},
3731
3732			// To know if the callbacks have already been called at least once
3733			fired: function() {
3734				return !!fired;
3735			}
3736		};
3737
3738	return self;
3739};
3740
3741
3742function Identity( v ) {
3743	return v;
3744}
3745function Thrower( ex ) {
3746	throw ex;
3747}
3748
3749function adoptValue( value, resolve, reject, noValue ) {
3750	var method;
3751
3752	try {
3753
3754		// Check for promise aspect first to privilege synchronous behavior
3755		if ( value && isFunction( ( method = value.promise ) ) ) {
3756			method.call( value ).done( resolve ).fail( reject );
3757
3758		// Other thenables
3759		} else if ( value && isFunction( ( method = value.then ) ) ) {
3760			method.call( value, resolve, reject );
3761
3762		// Other non-thenables
3763		} else {
3764
3765			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3766			// * false: [ value ].slice( 0 ) => resolve( value )
3767			// * true: [ value ].slice( 1 ) => resolve()
3768			resolve.apply( undefined, [ value ].slice( noValue ) );
3769		}
3770
3771	// For Promises/A+, convert exceptions into rejections
3772	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3773	// Deferred#then to conditionally suppress rejection.
3774	} catch ( value ) {
3775
3776		// Support: Android 4.0 only
3777		// Strict mode functions invoked without .call/.apply get global-object context
3778		reject.apply( undefined, [ value ] );
3779	}
3780}
3781
3782jQuery.extend( {
3783
3784	Deferred: function( func ) {
3785		var tuples = [
3786
3787				// action, add listener, callbacks,
3788				// ... .then handlers, argument index, [final state]
3789				[ "notify", "progress", jQuery.Callbacks( "memory" ),
3790					jQuery.Callbacks( "memory" ), 2 ],
3791				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
3792					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3793				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
3794					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3795			],
3796			state = "pending",
3797			promise = {
3798				state: function() {
3799					return state;
3800				},
3801				always: function() {
3802					deferred.done( arguments ).fail( arguments );
3803					return this;
3804				},
3805				"catch": function( fn ) {
3806					return promise.then( null, fn );
3807				},
3808
3809				// Keep pipe for back-compat
3810				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3811					var fns = arguments;
3812
3813					return jQuery.Deferred( function( newDefer ) {
3814						jQuery.each( tuples, function( _i, tuple ) {
3815
3816							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
3817							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3818
3819							// deferred.progress(function() { bind to newDefer or newDefer.notify })
3820							// deferred.done(function() { bind to newDefer or newDefer.resolve })
3821							// deferred.fail(function() { bind to newDefer or newDefer.reject })
3822							deferred[ tuple[ 1 ] ]( function() {
3823								var returned = fn && fn.apply( this, arguments );
3824								if ( returned && isFunction( returned.promise ) ) {
3825									returned.promise()
3826										.progress( newDefer.notify )
3827										.done( newDefer.resolve )
3828										.fail( newDefer.reject );
3829								} else {
3830									newDefer[ tuple[ 0 ] + "With" ](
3831										this,
3832										fn ? [ returned ] : arguments
3833									);
3834								}
3835							} );
3836						} );
3837						fns = null;
3838					} ).promise();
3839				},
3840				then: function( onFulfilled, onRejected, onProgress ) {
3841					var maxDepth = 0;
3842					function resolve( depth, deferred, handler, special ) {
3843						return function() {
3844							var that = this,
3845								args = arguments,
3846								mightThrow = function() {
3847									var returned, then;
3848
3849									// Support: Promises/A+ section 2.3.3.3.3
3850									// https://promisesaplus.com/#point-59
3851									// Ignore double-resolution attempts
3852									if ( depth < maxDepth ) {
3853										return;
3854									}
3855
3856									returned = handler.apply( that, args );
3857
3858									// Support: Promises/A+ section 2.3.1
3859									// https://promisesaplus.com/#point-48
3860									if ( returned === deferred.promise() ) {
3861										throw new TypeError( "Thenable self-resolution" );
3862									}
3863
3864									// Support: Promises/A+ sections 2.3.3.1, 3.5
3865									// https://promisesaplus.com/#point-54
3866									// https://promisesaplus.com/#point-75
3867									// Retrieve `then` only once
3868									then = returned &&
3869
3870										// Support: Promises/A+ section 2.3.4
3871										// https://promisesaplus.com/#point-64
3872										// Only check objects and functions for thenability
3873										( typeof returned === "object" ||
3874											typeof returned === "function" ) &&
3875										returned.then;
3876
3877									// Handle a returned thenable
3878									if ( isFunction( then ) ) {
3879
3880										// Special processors (notify) just wait for resolution
3881										if ( special ) {
3882											then.call(
3883												returned,
3884												resolve( maxDepth, deferred, Identity, special ),
3885												resolve( maxDepth, deferred, Thrower, special )
3886											);
3887
3888										// Normal processors (resolve) also hook into progress
3889										} else {
3890
3891											// ...and disregard older resolution values
3892											maxDepth++;
3893
3894											then.call(
3895												returned,
3896												resolve( maxDepth, deferred, Identity, special ),
3897												resolve( maxDepth, deferred, Thrower, special ),
3898												resolve( maxDepth, deferred, Identity,
3899													deferred.notifyWith )
3900											);
3901										}
3902
3903									// Handle all other returned values
3904									} else {
3905
3906										// Only substitute handlers pass on context
3907										// and multiple values (non-spec behavior)
3908										if ( handler !== Identity ) {
3909											that = undefined;
3910											args = [ returned ];
3911										}
3912
3913										// Process the value(s)
3914										// Default process is resolve
3915										( special || deferred.resolveWith )( that, args );
3916									}
3917								},
3918
3919								// Only normal processors (resolve) catch and reject exceptions
3920								process = special ?
3921									mightThrow :
3922									function() {
3923										try {
3924											mightThrow();
3925										} catch ( e ) {
3926
3927											if ( jQuery.Deferred.exceptionHook ) {
3928												jQuery.Deferred.exceptionHook( e,
3929													process.stackTrace );
3930											}
3931
3932											// Support: Promises/A+ section 2.3.3.3.4.1
3933											// https://promisesaplus.com/#point-61
3934											// Ignore post-resolution exceptions
3935											if ( depth + 1 >= maxDepth ) {
3936
3937												// Only substitute handlers pass on context
3938												// and multiple values (non-spec behavior)
3939												if ( handler !== Thrower ) {
3940													that = undefined;
3941													args = [ e ];
3942												}
3943
3944												deferred.rejectWith( that, args );
3945											}
3946										}
3947									};
3948
3949							// Support: Promises/A+ section 2.3.3.3.1
3950							// https://promisesaplus.com/#point-57
3951							// Re-resolve promises immediately to dodge false rejection from
3952							// subsequent errors
3953							if ( depth ) {
3954								process();
3955							} else {
3956
3957								// Call an optional hook to record the stack, in case of exception
3958								// since it's otherwise lost when execution goes async
3959								if ( jQuery.Deferred.getStackHook ) {
3960									process.stackTrace = jQuery.Deferred.getStackHook();
3961								}
3962								window.setTimeout( process );
3963							}
3964						};
3965					}
3966
3967					return jQuery.Deferred( function( newDefer ) {
3968
3969						// progress_handlers.add( ... )
3970						tuples[ 0 ][ 3 ].add(
3971							resolve(
3972								0,
3973								newDefer,
3974								isFunction( onProgress ) ?
3975									onProgress :
3976									Identity,
3977								newDefer.notifyWith
3978							)
3979						);
3980
3981						// fulfilled_handlers.add( ... )
3982						tuples[ 1 ][ 3 ].add(
3983							resolve(
3984								0,
3985								newDefer,
3986								isFunction( onFulfilled ) ?
3987									onFulfilled :
3988									Identity
3989							)
3990						);
3991
3992						// rejected_handlers.add( ... )
3993						tuples[ 2 ][ 3 ].add(
3994							resolve(
3995								0,
3996								newDefer,
3997								isFunction( onRejected ) ?
3998									onRejected :
3999									Thrower
4000							)
4001						);
4002					} ).promise();
4003				},
4004
4005				// Get a promise for this deferred
4006				// If obj is provided, the promise aspect is added to the object
4007				promise: function( obj ) {
4008					return obj != null ? jQuery.extend( obj, promise ) : promise;
4009				}
4010			},
4011			deferred = {};
4012
4013		// Add list-specific methods
4014		jQuery.each( tuples, function( i, tuple ) {
4015			var list = tuple[ 2 ],
4016				stateString = tuple[ 5 ];
4017
4018			// promise.progress = list.add
4019			// promise.done = list.add
4020			// promise.fail = list.add
4021			promise[ tuple[ 1 ] ] = list.add;
4022
4023			// Handle state
4024			if ( stateString ) {
4025				list.add(
4026					function() {
4027
4028						// state = "resolved" (i.e., fulfilled)
4029						// state = "rejected"
4030						state = stateString;
4031					},
4032
4033					// rejected_callbacks.disable
4034					// fulfilled_callbacks.disable
4035					tuples[ 3 - i ][ 2 ].disable,
4036
4037					// rejected_handlers.disable
4038					// fulfilled_handlers.disable
4039					tuples[ 3 - i ][ 3 ].disable,
4040
4041					// progress_callbacks.lock
4042					tuples[ 0 ][ 2 ].lock,
4043
4044					// progress_handlers.lock
4045					tuples[ 0 ][ 3 ].lock
4046				);
4047			}
4048
4049			// progress_handlers.fire
4050			// fulfilled_handlers.fire
4051			// rejected_handlers.fire
4052			list.add( tuple[ 3 ].fire );
4053
4054			// deferred.notify = function() { deferred.notifyWith(...) }
4055			// deferred.resolve = function() { deferred.resolveWith(...) }
4056			// deferred.reject = function() { deferred.rejectWith(...) }
4057			deferred[ tuple[ 0 ] ] = function() {
4058				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
4059				return this;
4060			};
4061
4062			// deferred.notifyWith = list.fireWith
4063			// deferred.resolveWith = list.fireWith
4064			// deferred.rejectWith = list.fireWith
4065			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
4066		} );
4067
4068		// Make the deferred a promise
4069		promise.promise( deferred );
4070
4071		// Call given func if any
4072		if ( func ) {
4073			func.call( deferred, deferred );
4074		}
4075
4076		// All done!
4077		return deferred;
4078	},
4079
4080	// Deferred helper
4081	when: function( singleValue ) {
4082		var
4083
4084			// count of uncompleted subordinates
4085			remaining = arguments.length,
4086
4087			// count of unprocessed arguments
4088			i = remaining,
4089
4090			// subordinate fulfillment data
4091			resolveContexts = Array( i ),
4092			resolveValues = slice.call( arguments ),
4093
4094			// the primary Deferred
4095			primary = jQuery.Deferred(),
4096
4097			// subordinate callback factory
4098			updateFunc = function( i ) {
4099				return function( value ) {
4100					resolveContexts[ i ] = this;
4101					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
4102					if ( !( --remaining ) ) {
4103						primary.resolveWith( resolveContexts, resolveValues );
4104					}
4105				};
4106			};
4107
4108		// Single- and empty arguments are adopted like Promise.resolve
4109		if ( remaining <= 1 ) {
4110			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
4111				!remaining );
4112
4113			// Use .then() to unwrap secondary thenables (cf. gh-3000)
4114			if ( primary.state() === "pending" ||
4115				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
4116
4117				return primary.then();
4118			}
4119		}
4120
4121		// Multiple arguments are aggregated like Promise.all array elements
4122		while ( i-- ) {
4123			adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
4124		}
4125
4126		return primary.promise();
4127	}
4128} );
4129
4130
4131// These usually indicate a programmer mistake during development,
4132// warn about them ASAP rather than swallowing them by default.
4133var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
4134
4135jQuery.Deferred.exceptionHook = function( error, stack ) {
4136
4137	// Support: IE 8 - 9 only
4138	// Console exists when dev tools are open, which can happen at any time
4139	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
4140		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
4141	}
4142};
4143
4144
4145
4146
4147jQuery.readyException = function( error ) {
4148	window.setTimeout( function() {
4149		throw error;
4150	} );
4151};
4152
4153
4154
4155
4156// The deferred used on DOM ready
4157var readyList = jQuery.Deferred();
4158
4159jQuery.fn.ready = function( fn ) {
4160
4161	readyList
4162		.then( fn )
4163
4164		// Wrap jQuery.readyException in a function so that the lookup
4165		// happens at the time of error handling instead of callback
4166		// registration.
4167		.catch( function( error ) {
4168			jQuery.readyException( error );
4169		} );
4170
4171	return this;
4172};
4173
4174jQuery.extend( {
4175
4176	// Is the DOM ready to be used? Set to true once it occurs.
4177	isReady: false,
4178
4179	// A counter to track how many items to wait for before
4180	// the ready event fires. See #6781
4181	readyWait: 1,
4182
4183	// Handle when the DOM is ready
4184	ready: function( wait ) {
4185
4186		// Abort if there are pending holds or we're already ready
4187		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
4188			return;
4189		}
4190
4191		// Remember that the DOM is ready
4192		jQuery.isReady = true;
4193
4194		// If a normal DOM Ready event fired, decrement, and wait if need be
4195		if ( wait !== true && --jQuery.readyWait > 0 ) {
4196			return;
4197		}
4198
4199		// If there are functions bound, to execute
4200		readyList.resolveWith( document, [ jQuery ] );
4201	}
4202} );
4203
4204jQuery.ready.then = readyList.then;
4205
4206// The ready event handler and self cleanup method
4207function completed() {
4208	document.removeEventListener( "DOMContentLoaded", completed );
4209	window.removeEventListener( "load", completed );
4210	jQuery.ready();
4211}
4212
4213// Catch cases where $(document).ready() is called
4214// after the browser event has already occurred.
4215// Support: IE <=9 - 10 only
4216// Older IE sometimes signals "interactive" too soon
4217if ( document.readyState === "complete" ||
4218	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
4219
4220	// Handle it asynchronously to allow scripts the opportunity to delay ready
4221	window.setTimeout( jQuery.ready );
4222
4223} else {
4224
4225	// Use the handy event callback
4226	document.addEventListener( "DOMContentLoaded", completed );
4227
4228	// A fallback to window.onload, that will always work
4229	window.addEventListener( "load", completed );
4230}
4231
4232
4233
4234
4235// Multifunctional method to get and set values of a collection
4236// The value/s can optionally be executed if it's a function
4237var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4238	var i = 0,
4239		len = elems.length,
4240		bulk = key == null;
4241
4242	// Sets many values
4243	if ( toType( key ) === "object" ) {
4244		chainable = true;
4245		for ( i in key ) {
4246			access( elems, fn, i, key[ i ], true, emptyGet, raw );
4247		}
4248
4249	// Sets one value
4250	} else if ( value !== undefined ) {
4251		chainable = true;
4252
4253		if ( !isFunction( value ) ) {
4254			raw = true;
4255		}
4256
4257		if ( bulk ) {
4258
4259			// Bulk operations run against the entire set
4260			if ( raw ) {
4261				fn.call( elems, value );
4262				fn = null;
4263
4264			// ...except when executing function values
4265			} else {
4266				bulk = fn;
4267				fn = function( elem, _key, value ) {
4268					return bulk.call( jQuery( elem ), value );
4269				};
4270			}
4271		}
4272
4273		if ( fn ) {
4274			for ( ; i < len; i++ ) {
4275				fn(
4276					elems[ i ], key, raw ?
4277						value :
4278						value.call( elems[ i ], i, fn( elems[ i ], key ) )
4279				);
4280			}
4281		}
4282	}
4283
4284	if ( chainable ) {
4285		return elems;
4286	}
4287
4288	// Gets
4289	if ( bulk ) {
4290		return fn.call( elems );
4291	}
4292
4293	return len ? fn( elems[ 0 ], key ) : emptyGet;
4294};
4295
4296
4297// Matches dashed string for camelizing
4298var rmsPrefix = /^-ms-/,
4299	rdashAlpha = /-([a-z])/g;
4300
4301// Used by camelCase as callback to replace()
4302function fcamelCase( _all, letter ) {
4303	return letter.toUpperCase();
4304}
4305
4306// Convert dashed to camelCase; used by the css and data modules
4307// Support: IE <=9 - 11, Edge 12 - 15
4308// Microsoft forgot to hump their vendor prefix (#9572)
4309function camelCase( string ) {
4310	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
4311}
4312var acceptData = function( owner ) {
4313
4314	// Accepts only:
4315	//  - Node
4316	//    - Node.ELEMENT_NODE
4317	//    - Node.DOCUMENT_NODE
4318	//  - Object
4319	//    - Any
4320	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4321};
4322
4323
4324
4325
4326function Data() {
4327	this.expando = jQuery.expando + Data.uid++;
4328}
4329
4330Data.uid = 1;
4331
4332Data.prototype = {
4333
4334	cache: function( owner ) {
4335
4336		// Check if the owner object already has a cache
4337		var value = owner[ this.expando ];
4338
4339		// If not, create one
4340		if ( !value ) {
4341			value = {};
4342
4343			// We can accept data for non-element nodes in modern browsers,
4344			// but we should not, see #8335.
4345			// Always return an empty object.
4346			if ( acceptData( owner ) ) {
4347
4348				// If it is a node unlikely to be stringify-ed or looped over
4349				// use plain assignment
4350				if ( owner.nodeType ) {
4351					owner[ this.expando ] = value;
4352
4353				// Otherwise secure it in a non-enumerable property
4354				// configurable must be true to allow the property to be
4355				// deleted when data is removed
4356				} else {
4357					Object.defineProperty( owner, this.expando, {
4358						value: value,
4359						configurable: true
4360					} );
4361				}
4362			}
4363		}
4364
4365		return value;
4366	},
4367	set: function( owner, data, value ) {
4368		var prop,
4369			cache = this.cache( owner );
4370
4371		// Handle: [ owner, key, value ] args
4372		// Always use camelCase key (gh-2257)
4373		if ( typeof data === "string" ) {
4374			cache[ camelCase( data ) ] = value;
4375
4376		// Handle: [ owner, { properties } ] args
4377		} else {
4378
4379			// Copy the properties one-by-one to the cache object
4380			for ( prop in data ) {
4381				cache[ camelCase( prop ) ] = data[ prop ];
4382			}
4383		}
4384		return cache;
4385	},
4386	get: function( owner, key ) {
4387		return key === undefined ?
4388			this.cache( owner ) :
4389
4390			// Always use camelCase key (gh-2257)
4391			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4392	},
4393	access: function( owner, key, value ) {
4394
4395		// In cases where either:
4396		//
4397		//   1. No key was specified
4398		//   2. A string key was specified, but no value provided
4399		//
4400		// Take the "read" path and allow the get method to determine
4401		// which value to return, respectively either:
4402		//
4403		//   1. The entire cache object
4404		//   2. The data stored at the key
4405		//
4406		if ( key === undefined ||
4407				( ( key && typeof key === "string" ) && value === undefined ) ) {
4408
4409			return this.get( owner, key );
4410		}
4411
4412		// When the key is not a string, or both a key and value
4413		// are specified, set or extend (existing objects) with either:
4414		//
4415		//   1. An object of properties
4416		//   2. A key and value
4417		//
4418		this.set( owner, key, value );
4419
4420		// Since the "set" path can have two possible entry points
4421		// return the expected data based on which path was taken[*]
4422		return value !== undefined ? value : key;
4423	},
4424	remove: function( owner, key ) {
4425		var i,
4426			cache = owner[ this.expando ];
4427
4428		if ( cache === undefined ) {
4429			return;
4430		}
4431
4432		if ( key !== undefined ) {
4433
4434			// Support array or space separated string of keys
4435			if ( Array.isArray( key ) ) {
4436
4437				// If key is an array of keys...
4438				// We always set camelCase keys, so remove that.
4439				key = key.map( camelCase );
4440			} else {
4441				key = camelCase( key );
4442
4443				// If a key with the spaces exists, use it.
4444				// Otherwise, create an array by matching non-whitespace
4445				key = key in cache ?
4446					[ key ] :
4447					( key.match( rnothtmlwhite ) || [] );
4448			}
4449
4450			i = key.length;
4451
4452			while ( i-- ) {
4453				delete cache[ key[ i ] ];
4454			}
4455		}
4456
4457		// Remove the expando if there's no more data
4458		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4459
4460			// Support: Chrome <=35 - 45
4461			// Webkit & Blink performance suffers when deleting properties
4462			// from DOM nodes, so set to undefined instead
4463			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4464			if ( owner.nodeType ) {
4465				owner[ this.expando ] = undefined;
4466			} else {
4467				delete owner[ this.expando ];
4468			}
4469		}
4470	},
4471	hasData: function( owner ) {
4472		var cache = owner[ this.expando ];
4473		return cache !== undefined && !jQuery.isEmptyObject( cache );
4474	}
4475};
4476var dataPriv = new Data();
4477
4478var dataUser = new Data();
4479
4480
4481
4482//	Implementation Summary
4483//
4484//	1. Enforce API surface and semantic compatibility with 1.9.x branch
4485//	2. Improve the module's maintainability by reducing the storage
4486//		paths to a single mechanism.
4487//	3. Use the same single mechanism to support "private" and "user" data.
4488//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4489//	5. Avoid exposing implementation details on user objects (eg. expando properties)
4490//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
4491
4492var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4493	rmultiDash = /[A-Z]/g;
4494
4495function getData( data ) {
4496	if ( data === "true" ) {
4497		return true;
4498	}
4499
4500	if ( data === "false" ) {
4501		return false;
4502	}
4503
4504	if ( data === "null" ) {
4505		return null;
4506	}
4507
4508	// Only convert to a number if it doesn't change the string
4509	if ( data === +data + "" ) {
4510		return +data;
4511	}
4512
4513	if ( rbrace.test( data ) ) {
4514		return JSON.parse( data );
4515	}
4516
4517	return data;
4518}
4519
4520function dataAttr( elem, key, data ) {
4521	var name;
4522
4523	// If nothing was found internally, try to fetch any
4524	// data from the HTML5 data-* attribute
4525	if ( data === undefined && elem.nodeType === 1 ) {
4526		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4527		data = elem.getAttribute( name );
4528
4529		if ( typeof data === "string" ) {
4530			try {
4531				data = getData( data );
4532			} catch ( e ) {}
4533
4534			// Make sure we set the data so it isn't changed later
4535			dataUser.set( elem, key, data );
4536		} else {
4537			data = undefined;
4538		}
4539	}
4540	return data;
4541}
4542
4543jQuery.extend( {
4544	hasData: function( elem ) {
4545		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4546	},
4547
4548	data: function( elem, name, data ) {
4549		return dataUser.access( elem, name, data );
4550	},
4551
4552	removeData: function( elem, name ) {
4553		dataUser.remove( elem, name );
4554	},
4555
4556	// TODO: Now that all calls to _data and _removeData have been replaced
4557	// with direct calls to dataPriv methods, these can be deprecated.
4558	_data: function( elem, name, data ) {
4559		return dataPriv.access( elem, name, data );
4560	},
4561
4562	_removeData: function( elem, name ) {
4563		dataPriv.remove( elem, name );
4564	}
4565} );
4566
4567jQuery.fn.extend( {
4568	data: function( key, value ) {
4569		var i, name, data,
4570			elem = this[ 0 ],
4571			attrs = elem && elem.attributes;
4572
4573		// Gets all values
4574		if ( key === undefined ) {
4575			if ( this.length ) {
4576				data = dataUser.get( elem );
4577
4578				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4579					i = attrs.length;
4580					while ( i-- ) {
4581
4582						// Support: IE 11 only
4583						// The attrs elements can be null (#14894)
4584						if ( attrs[ i ] ) {
4585							name = attrs[ i ].name;
4586							if ( name.indexOf( "data-" ) === 0 ) {
4587								name = camelCase( name.slice( 5 ) );
4588								dataAttr( elem, name, data[ name ] );
4589							}
4590						}
4591					}
4592					dataPriv.set( elem, "hasDataAttrs", true );
4593				}
4594			}
4595
4596			return data;
4597		}
4598
4599		// Sets multiple values
4600		if ( typeof key === "object" ) {
4601			return this.each( function() {
4602				dataUser.set( this, key );
4603			} );
4604		}
4605
4606		return access( this, function( value ) {
4607			var data;
4608
4609			// The calling jQuery object (element matches) is not empty
4610			// (and therefore has an element appears at this[ 0 ]) and the
4611			// `value` parameter was not undefined. An empty jQuery object
4612			// will result in `undefined` for elem = this[ 0 ] which will
4613			// throw an exception if an attempt to read a data cache is made.
4614			if ( elem && value === undefined ) {
4615
4616				// Attempt to get data from the cache
4617				// The key will always be camelCased in Data
4618				data = dataUser.get( elem, key );
4619				if ( data !== undefined ) {
4620					return data;
4621				}
4622
4623				// Attempt to "discover" the data in
4624				// HTML5 custom data-* attrs
4625				data = dataAttr( elem, key );
4626				if ( data !== undefined ) {
4627					return data;
4628				}
4629
4630				// We tried really hard, but the data doesn't exist.
4631				return;
4632			}
4633
4634			// Set the data...
4635			this.each( function() {
4636
4637				// We always store the camelCased key
4638				dataUser.set( this, key, value );
4639			} );
4640		}, null, value, arguments.length > 1, null, true );
4641	},
4642
4643	removeData: function( key ) {
4644		return this.each( function() {
4645			dataUser.remove( this, key );
4646		} );
4647	}
4648} );
4649
4650
4651jQuery.extend( {
4652	queue: function( elem, type, data ) {
4653		var queue;
4654
4655		if ( elem ) {
4656			type = ( type || "fx" ) + "queue";
4657			queue = dataPriv.get( elem, type );
4658
4659			// Speed up dequeue by getting out quickly if this is just a lookup
4660			if ( data ) {
4661				if ( !queue || Array.isArray( data ) ) {
4662					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4663				} else {
4664					queue.push( data );
4665				}
4666			}
4667			return queue || [];
4668		}
4669	},
4670
4671	dequeue: function( elem, type ) {
4672		type = type || "fx";
4673
4674		var queue = jQuery.queue( elem, type ),
4675			startLength = queue.length,
4676			fn = queue.shift(),
4677			hooks = jQuery._queueHooks( elem, type ),
4678			next = function() {
4679				jQuery.dequeue( elem, type );
4680			};
4681
4682		// If the fx queue is dequeued, always remove the progress sentinel
4683		if ( fn === "inprogress" ) {
4684			fn = queue.shift();
4685			startLength--;
4686		}
4687
4688		if ( fn ) {
4689
4690			// Add a progress sentinel to prevent the fx queue from being
4691			// automatically dequeued
4692			if ( type === "fx" ) {
4693				queue.unshift( "inprogress" );
4694			}
4695
4696			// Clear up the last queue stop function
4697			delete hooks.stop;
4698			fn.call( elem, next, hooks );
4699		}
4700
4701		if ( !startLength && hooks ) {
4702			hooks.empty.fire();
4703		}
4704	},
4705
4706	// Not public - generate a queueHooks object, or return the current one
4707	_queueHooks: function( elem, type ) {
4708		var key = type + "queueHooks";
4709		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4710			empty: jQuery.Callbacks( "once memory" ).add( function() {
4711				dataPriv.remove( elem, [ type + "queue", key ] );
4712			} )
4713		} );
4714	}
4715} );
4716
4717jQuery.fn.extend( {
4718	queue: function( type, data ) {
4719		var setter = 2;
4720
4721		if ( typeof type !== "string" ) {
4722			data = type;
4723			type = "fx";
4724			setter--;
4725		}
4726
4727		if ( arguments.length < setter ) {
4728			return jQuery.queue( this[ 0 ], type );
4729		}
4730
4731		return data === undefined ?
4732			this :
4733			this.each( function() {
4734				var queue = jQuery.queue( this, type, data );
4735
4736				// Ensure a hooks for this queue
4737				jQuery._queueHooks( this, type );
4738
4739				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4740					jQuery.dequeue( this, type );
4741				}
4742			} );
4743	},
4744	dequeue: function( type ) {
4745		return this.each( function() {
4746			jQuery.dequeue( this, type );
4747		} );
4748	},
4749	clearQueue: function( type ) {
4750		return this.queue( type || "fx", [] );
4751	},
4752
4753	// Get a promise resolved when queues of a certain type
4754	// are emptied (fx is the type by default)
4755	promise: function( type, obj ) {
4756		var tmp,
4757			count = 1,
4758			defer = jQuery.Deferred(),
4759			elements = this,
4760			i = this.length,
4761			resolve = function() {
4762				if ( !( --count ) ) {
4763					defer.resolveWith( elements, [ elements ] );
4764				}
4765			};
4766
4767		if ( typeof type !== "string" ) {
4768			obj = type;
4769			type = undefined;
4770		}
4771		type = type || "fx";
4772
4773		while ( i-- ) {
4774			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4775			if ( tmp && tmp.empty ) {
4776				count++;
4777				tmp.empty.add( resolve );
4778			}
4779		}
4780		resolve();
4781		return defer.promise( obj );
4782	}
4783} );
4784var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4785
4786var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4787
4788
4789var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4790
4791var documentElement = document.documentElement;
4792
4793
4794
4795	var isAttached = function( elem ) {
4796			return jQuery.contains( elem.ownerDocument, elem );
4797		},
4798		composed = { composed: true };
4799
4800	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
4801	// Check attachment across shadow DOM boundaries when possible (gh-3504)
4802	// Support: iOS 10.0-10.2 only
4803	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
4804	// leading to errors. We need to check for `getRootNode`.
4805	if ( documentElement.getRootNode ) {
4806		isAttached = function( elem ) {
4807			return jQuery.contains( elem.ownerDocument, elem ) ||
4808				elem.getRootNode( composed ) === elem.ownerDocument;
4809		};
4810	}
4811var isHiddenWithinTree = function( elem, el ) {
4812
4813		// isHiddenWithinTree might be called from jQuery#filter function;
4814		// in that case, element will be second argument
4815		elem = el || elem;
4816
4817		// Inline style trumps all
4818		return elem.style.display === "none" ||
4819			elem.style.display === "" &&
4820
4821			// Otherwise, check computed style
4822			// Support: Firefox <=43 - 45
4823			// Disconnected elements can have computed display: none, so first confirm that elem is
4824			// in the document.
4825			isAttached( elem ) &&
4826
4827			jQuery.css( elem, "display" ) === "none";
4828	};
4829
4830
4831
4832function adjustCSS( elem, prop, valueParts, tween ) {
4833	var adjusted, scale,
4834		maxIterations = 20,
4835		currentValue = tween ?
4836			function() {
4837				return tween.cur();
4838			} :
4839			function() {
4840				return jQuery.css( elem, prop, "" );
4841			},
4842		initial = currentValue(),
4843		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4844
4845		// Starting value computation is required for potential unit mismatches
4846		initialInUnit = elem.nodeType &&
4847			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4848			rcssNum.exec( jQuery.css( elem, prop ) );
4849
4850	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4851
4852		// Support: Firefox <=54
4853		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4854		initial = initial / 2;
4855
4856		// Trust units reported by jQuery.css
4857		unit = unit || initialInUnit[ 3 ];
4858
4859		// Iteratively approximate from a nonzero starting point
4860		initialInUnit = +initial || 1;
4861
4862		while ( maxIterations-- ) {
4863
4864			// Evaluate and update our best guess (doubling guesses that zero out).
4865			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4866			jQuery.style( elem, prop, initialInUnit + unit );
4867			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
4868				maxIterations = 0;
4869			}
4870			initialInUnit = initialInUnit / scale;
4871
4872		}
4873
4874		initialInUnit = initialInUnit * 2;
4875		jQuery.style( elem, prop, initialInUnit + unit );
4876
4877		// Make sure we update the tween properties later on
4878		valueParts = valueParts || [];
4879	}
4880
4881	if ( valueParts ) {
4882		initialInUnit = +initialInUnit || +initial || 0;
4883
4884		// Apply relative offset (+=/-=) if specified
4885		adjusted = valueParts[ 1 ] ?
4886			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4887			+valueParts[ 2 ];
4888		if ( tween ) {
4889			tween.unit = unit;
4890			tween.start = initialInUnit;
4891			tween.end = adjusted;
4892		}
4893	}
4894	return adjusted;
4895}
4896
4897
4898var defaultDisplayMap = {};
4899
4900function getDefaultDisplay( elem ) {
4901	var temp,
4902		doc = elem.ownerDocument,
4903		nodeName = elem.nodeName,
4904		display = defaultDisplayMap[ nodeName ];
4905
4906	if ( display ) {
4907		return display;
4908	}
4909
4910	temp = doc.body.appendChild( doc.createElement( nodeName ) );
4911	display = jQuery.css( temp, "display" );
4912
4913	temp.parentNode.removeChild( temp );
4914
4915	if ( display === "none" ) {
4916		display = "block";
4917	}
4918	defaultDisplayMap[ nodeName ] = display;
4919
4920	return display;
4921}
4922
4923function showHide( elements, show ) {
4924	var display, elem,
4925		values = [],
4926		index = 0,
4927		length = elements.length;
4928
4929	// Determine new display value for elements that need to change
4930	for ( ; index < length; index++ ) {
4931		elem = elements[ index ];
4932		if ( !elem.style ) {
4933			continue;
4934		}
4935
4936		display = elem.style.display;
4937		if ( show ) {
4938
4939			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4940			// check is required in this first loop unless we have a nonempty display value (either
4941			// inline or about-to-be-restored)
4942			if ( display === "none" ) {
4943				values[ index ] = dataPriv.get( elem, "display" ) || null;
4944				if ( !values[ index ] ) {
4945					elem.style.display = "";
4946				}
4947			}
4948			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4949				values[ index ] = getDefaultDisplay( elem );
4950			}
4951		} else {
4952			if ( display !== "none" ) {
4953				values[ index ] = "none";
4954
4955				// Remember what we're overwriting
4956				dataPriv.set( elem, "display", display );
4957			}
4958		}
4959	}
4960
4961	// Set the display of the elements in a second loop to avoid constant reflow
4962	for ( index = 0; index < length; index++ ) {
4963		if ( values[ index ] != null ) {
4964			elements[ index ].style.display = values[ index ];
4965		}
4966	}
4967
4968	return elements;
4969}
4970
4971jQuery.fn.extend( {
4972	show: function() {
4973		return showHide( this, true );
4974	},
4975	hide: function() {
4976		return showHide( this );
4977	},
4978	toggle: function( state ) {
4979		if ( typeof state === "boolean" ) {
4980			return state ? this.show() : this.hide();
4981		}
4982
4983		return this.each( function() {
4984			if ( isHiddenWithinTree( this ) ) {
4985				jQuery( this ).show();
4986			} else {
4987				jQuery( this ).hide();
4988			}
4989		} );
4990	}
4991} );
4992var rcheckableType = ( /^(?:checkbox|radio)$/i );
4993
4994var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
4995
4996var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
4997
4998
4999
5000( function() {
5001	var fragment = document.createDocumentFragment(),
5002		div = fragment.appendChild( document.createElement( "div" ) ),
5003		input = document.createElement( "input" );
5004
5005	// Support: Android 4.0 - 4.3 only
5006	// Check state lost if the name is set (#11217)
5007	// Support: Windows Web Apps (WWA)
5008	// `name` and `type` must use .setAttribute for WWA (#14901)
5009	input.setAttribute( "type", "radio" );
5010	input.setAttribute( "checked", "checked" );
5011	input.setAttribute( "name", "t" );
5012
5013	div.appendChild( input );
5014
5015	// Support: Android <=4.1 only
5016	// Older WebKit doesn't clone checked state correctly in fragments
5017	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
5018
5019	// Support: IE <=11 only
5020	// Make sure textarea (and checkbox) defaultValue is properly cloned
5021	div.innerHTML = "<textarea>x</textarea>";
5022	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
5023
5024	// Support: IE <=9 only
5025	// IE <=9 replaces <option> tags with their contents when inserted outside of
5026	// the select element.
5027	div.innerHTML = "<option></option>";
5028	support.option = !!div.lastChild;
5029} )();
5030
5031
5032// We have to close these tags to support XHTML (#13200)
5033var wrapMap = {
5034
5035	// XHTML parsers do not magically insert elements in the
5036	// same way that tag soup parsers do. So we cannot shorten
5037	// this by omitting <tbody> or other required elements.
5038	thead: [ 1, "<table>", "</table>" ],
5039	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
5040	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5041	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5042
5043	_default: [ 0, "", "" ]
5044};
5045
5046wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5047wrapMap.th = wrapMap.td;
5048
5049// Support: IE <=9 only
5050if ( !support.option ) {
5051	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
5052}
5053
5054
5055function getAll( context, tag ) {
5056
5057	// Support: IE <=9 - 11 only
5058	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
5059	var ret;
5060
5061	if ( typeof context.getElementsByTagName !== "undefined" ) {
5062		ret = context.getElementsByTagName( tag || "*" );
5063
5064	} else if ( typeof context.querySelectorAll !== "undefined" ) {
5065		ret = context.querySelectorAll( tag || "*" );
5066
5067	} else {
5068		ret = [];
5069	}
5070
5071	if ( tag === undefined || tag && nodeName( context, tag ) ) {
5072		return jQuery.merge( [ context ], ret );
5073	}
5074
5075	return ret;
5076}
5077
5078
5079// Mark scripts as having already been evaluated
5080function setGlobalEval( elems, refElements ) {
5081	var i = 0,
5082		l = elems.length;
5083
5084	for ( ; i < l; i++ ) {
5085		dataPriv.set(
5086			elems[ i ],
5087			"globalEval",
5088			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
5089		);
5090	}
5091}
5092
5093
5094var rhtml = /<|&#?\w+;/;
5095
5096function buildFragment( elems, context, scripts, selection, ignored ) {
5097	var elem, tmp, tag, wrap, attached, j,
5098		fragment = context.createDocumentFragment(),
5099		nodes = [],
5100		i = 0,
5101		l = elems.length;
5102
5103	for ( ; i < l; i++ ) {
5104		elem = elems[ i ];
5105
5106		if ( elem || elem === 0 ) {
5107
5108			// Add nodes directly
5109			if ( toType( elem ) === "object" ) {
5110
5111				// Support: Android <=4.0 only, PhantomJS 1 only
5112				// push.apply(_, arraylike) throws on ancient WebKit
5113				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5114
5115			// Convert non-html into a text node
5116			} else if ( !rhtml.test( elem ) ) {
5117				nodes.push( context.createTextNode( elem ) );
5118
5119			// Convert html into DOM nodes
5120			} else {
5121				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
5122
5123				// Deserialize a standard representation
5124				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5125				wrap = wrapMap[ tag ] || wrapMap._default;
5126				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
5127
5128				// Descend through wrappers to the right content
5129				j = wrap[ 0 ];
5130				while ( j-- ) {
5131					tmp = tmp.lastChild;
5132				}
5133
5134				// Support: Android <=4.0 only, PhantomJS 1 only
5135				// push.apply(_, arraylike) throws on ancient WebKit
5136				jQuery.merge( nodes, tmp.childNodes );
5137
5138				// Remember the top-level container
5139				tmp = fragment.firstChild;
5140
5141				// Ensure the created nodes are orphaned (#12392)
5142				tmp.textContent = "";
5143			}
5144		}
5145	}
5146
5147	// Remove wrapper from fragment
5148	fragment.textContent = "";
5149
5150	i = 0;
5151	while ( ( elem = nodes[ i++ ] ) ) {
5152
5153		// Skip elements already in the context collection (trac-4087)
5154		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
5155			if ( ignored ) {
5156				ignored.push( elem );
5157			}
5158			continue;
5159		}
5160
5161		attached = isAttached( elem );
5162
5163		// Append to fragment
5164		tmp = getAll( fragment.appendChild( elem ), "script" );
5165
5166		// Preserve script evaluation history
5167		if ( attached ) {
5168			setGlobalEval( tmp );
5169		}
5170
5171		// Capture executables
5172		if ( scripts ) {
5173			j = 0;
5174			while ( ( elem = tmp[ j++ ] ) ) {
5175				if ( rscriptType.test( elem.type || "" ) ) {
5176					scripts.push( elem );
5177				}
5178			}
5179		}
5180	}
5181
5182	return fragment;
5183}
5184
5185
5186var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5187
5188function returnTrue() {
5189	return true;
5190}
5191
5192function returnFalse() {
5193	return false;
5194}
5195
5196// Support: IE <=9 - 11+
5197// focus() and blur() are asynchronous, except when they are no-op.
5198// So expect focus to be synchronous when the element is already active,
5199// and blur to be synchronous when the element is not already active.
5200// (focus and blur are always synchronous in other supported browsers,
5201// this just defines when we can count on it).
5202function expectSync( elem, type ) {
5203	return ( elem === safeActiveElement() ) === ( type === "focus" );
5204}
5205
5206// Support: IE <=9 only
5207// Accessing document.activeElement can throw unexpectedly
5208// https://bugs.jquery.com/ticket/13393
5209function safeActiveElement() {
5210	try {
5211		return document.activeElement;
5212	} catch ( err ) { }
5213}
5214
5215function on( elem, types, selector, data, fn, one ) {
5216	var origFn, type;
5217
5218	// Types can be a map of types/handlers
5219	if ( typeof types === "object" ) {
5220
5221		// ( types-Object, selector, data )
5222		if ( typeof selector !== "string" ) {
5223
5224			// ( types-Object, data )
5225			data = data || selector;
5226			selector = undefined;
5227		}
5228		for ( type in types ) {
5229			on( elem, type, selector, data, types[ type ], one );
5230		}
5231		return elem;
5232	}
5233
5234	if ( data == null && fn == null ) {
5235
5236		// ( types, fn )
5237		fn = selector;
5238		data = selector = undefined;
5239	} else if ( fn == null ) {
5240		if ( typeof selector === "string" ) {
5241
5242			// ( types, selector, fn )
5243			fn = data;
5244			data = undefined;
5245		} else {
5246
5247			// ( types, data, fn )
5248			fn = data;
5249			data = selector;
5250			selector = undefined;
5251		}
5252	}
5253	if ( fn === false ) {
5254		fn = returnFalse;
5255	} else if ( !fn ) {
5256		return elem;
5257	}
5258
5259	if ( one === 1 ) {
5260		origFn = fn;
5261		fn = function( event ) {
5262
5263			// Can use an empty set, since event contains the info
5264			jQuery().off( event );
5265			return origFn.apply( this, arguments );
5266		};
5267
5268		// Use same guid so caller can remove using origFn
5269		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5270	}
5271	return elem.each( function() {
5272		jQuery.event.add( this, types, fn, data, selector );
5273	} );
5274}
5275
5276/*
5277 * Helper functions for managing events -- not part of the public interface.
5278 * Props to Dean Edwards' addEvent library for many of the ideas.
5279 */
5280jQuery.event = {
5281
5282	global: {},
5283
5284	add: function( elem, types, handler, data, selector ) {
5285
5286		var handleObjIn, eventHandle, tmp,
5287			events, t, handleObj,
5288			special, handlers, type, namespaces, origType,
5289			elemData = dataPriv.get( elem );
5290
5291		// Only attach events to objects that accept data
5292		if ( !acceptData( elem ) ) {
5293			return;
5294		}
5295
5296		// Caller can pass in an object of custom data in lieu of the handler
5297		if ( handler.handler ) {
5298			handleObjIn = handler;
5299			handler = handleObjIn.handler;
5300			selector = handleObjIn.selector;
5301		}
5302
5303		// Ensure that invalid selectors throw exceptions at attach time
5304		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
5305		if ( selector ) {
5306			jQuery.find.matchesSelector( documentElement, selector );
5307		}
5308
5309		// Make sure that the handler has a unique ID, used to find/remove it later
5310		if ( !handler.guid ) {
5311			handler.guid = jQuery.guid++;
5312		}
5313
5314		// Init the element's event structure and main handler, if this is the first
5315		if ( !( events = elemData.events ) ) {
5316			events = elemData.events = Object.create( null );
5317		}
5318		if ( !( eventHandle = elemData.handle ) ) {
5319			eventHandle = elemData.handle = function( e ) {
5320
5321				// Discard the second event of a jQuery.event.trigger() and
5322				// when an event is called after a page has unloaded
5323				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5324					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5325			};
5326		}
5327
5328		// Handle multiple events separated by a space
5329		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5330		t = types.length;
5331		while ( t-- ) {
5332			tmp = rtypenamespace.exec( types[ t ] ) || [];
5333			type = origType = tmp[ 1 ];
5334			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5335
5336			// There *must* be a type, no attaching namespace-only handlers
5337			if ( !type ) {
5338				continue;
5339			}
5340
5341			// If event changes its type, use the special event handlers for the changed type
5342			special = jQuery.event.special[ type ] || {};
5343
5344			// If selector defined, determine special event api type, otherwise given type
5345			type = ( selector ? special.delegateType : special.bindType ) || type;
5346
5347			// Update special based on newly reset type
5348			special = jQuery.event.special[ type ] || {};
5349
5350			// handleObj is passed to all event handlers
5351			handleObj = jQuery.extend( {
5352				type: type,
5353				origType: origType,
5354				data: data,
5355				handler: handler,
5356				guid: handler.guid,
5357				selector: selector,
5358				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5359				namespace: namespaces.join( "." )
5360			}, handleObjIn );
5361
5362			// Init the event handler queue if we're the first
5363			if ( !( handlers = events[ type ] ) ) {
5364				handlers = events[ type ] = [];
5365				handlers.delegateCount = 0;
5366
5367				// Only use addEventListener if the special events handler returns false
5368				if ( !special.setup ||
5369					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5370
5371					if ( elem.addEventListener ) {
5372						elem.addEventListener( type, eventHandle );
5373					}
5374				}
5375			}
5376
5377			if ( special.add ) {
5378				special.add.call( elem, handleObj );
5379
5380				if ( !handleObj.handler.guid ) {
5381					handleObj.handler.guid = handler.guid;
5382				}
5383			}
5384
5385			// Add to the element's handler list, delegates in front
5386			if ( selector ) {
5387				handlers.splice( handlers.delegateCount++, 0, handleObj );
5388			} else {
5389				handlers.push( handleObj );
5390			}
5391
5392			// Keep track of which events have ever been used, for event optimization
5393			jQuery.event.global[ type ] = true;
5394		}
5395
5396	},
5397
5398	// Detach an event or set of events from an element
5399	remove: function( elem, types, handler, selector, mappedTypes ) {
5400
5401		var j, origCount, tmp,
5402			events, t, handleObj,
5403			special, handlers, type, namespaces, origType,
5404			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5405
5406		if ( !elemData || !( events = elemData.events ) ) {
5407			return;
5408		}
5409
5410		// Once for each type.namespace in types; type may be omitted
5411		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5412		t = types.length;
5413		while ( t-- ) {
5414			tmp = rtypenamespace.exec( types[ t ] ) || [];
5415			type = origType = tmp[ 1 ];
5416			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5417
5418			// Unbind all events (on this namespace, if provided) for the element
5419			if ( !type ) {
5420				for ( type in events ) {
5421					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5422				}
5423				continue;
5424			}
5425
5426			special = jQuery.event.special[ type ] || {};
5427			type = ( selector ? special.delegateType : special.bindType ) || type;
5428			handlers = events[ type ] || [];
5429			tmp = tmp[ 2 ] &&
5430				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5431
5432			// Remove matching events
5433			origCount = j = handlers.length;
5434			while ( j-- ) {
5435				handleObj = handlers[ j ];
5436
5437				if ( ( mappedTypes || origType === handleObj.origType ) &&
5438					( !handler || handler.guid === handleObj.guid ) &&
5439					( !tmp || tmp.test( handleObj.namespace ) ) &&
5440					( !selector || selector === handleObj.selector ||
5441						selector === "**" && handleObj.selector ) ) {
5442					handlers.splice( j, 1 );
5443
5444					if ( handleObj.selector ) {
5445						handlers.delegateCount--;
5446					}
5447					if ( special.remove ) {
5448						special.remove.call( elem, handleObj );
5449					}
5450				}
5451			}
5452
5453			// Remove generic event handler if we removed something and no more handlers exist
5454			// (avoids potential for endless recursion during removal of special event handlers)
5455			if ( origCount && !handlers.length ) {
5456				if ( !special.teardown ||
5457					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5458
5459					jQuery.removeEvent( elem, type, elemData.handle );
5460				}
5461
5462				delete events[ type ];
5463			}
5464		}
5465
5466		// Remove data and the expando if it's no longer used
5467		if ( jQuery.isEmptyObject( events ) ) {
5468			dataPriv.remove( elem, "handle events" );
5469		}
5470	},
5471
5472	dispatch: function( nativeEvent ) {
5473
5474		var i, j, ret, matched, handleObj, handlerQueue,
5475			args = new Array( arguments.length ),
5476
5477			// Make a writable jQuery.Event from the native event object
5478			event = jQuery.event.fix( nativeEvent ),
5479
5480			handlers = (
5481				dataPriv.get( this, "events" ) || Object.create( null )
5482			)[ event.type ] || [],
5483			special = jQuery.event.special[ event.type ] || {};
5484
5485		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5486		args[ 0 ] = event;
5487
5488		for ( i = 1; i < arguments.length; i++ ) {
5489			args[ i ] = arguments[ i ];
5490		}
5491
5492		event.delegateTarget = this;
5493
5494		// Call the preDispatch hook for the mapped type, and let it bail if desired
5495		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5496			return;
5497		}
5498
5499		// Determine handlers
5500		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5501
5502		// Run delegates first; they may want to stop propagation beneath us
5503		i = 0;
5504		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5505			event.currentTarget = matched.elem;
5506
5507			j = 0;
5508			while ( ( handleObj = matched.handlers[ j++ ] ) &&
5509				!event.isImmediatePropagationStopped() ) {
5510
5511				// If the event is namespaced, then each handler is only invoked if it is
5512				// specially universal or its namespaces are a superset of the event's.
5513				if ( !event.rnamespace || handleObj.namespace === false ||
5514					event.rnamespace.test( handleObj.namespace ) ) {
5515
5516					event.handleObj = handleObj;
5517					event.data = handleObj.data;
5518
5519					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5520						handleObj.handler ).apply( matched.elem, args );
5521
5522					if ( ret !== undefined ) {
5523						if ( ( event.result = ret ) === false ) {
5524							event.preventDefault();
5525							event.stopPropagation();
5526						}
5527					}
5528				}
5529			}
5530		}
5531
5532		// Call the postDispatch hook for the mapped type
5533		if ( special.postDispatch ) {
5534			special.postDispatch.call( this, event );
5535		}
5536
5537		return event.result;
5538	},
5539
5540	handlers: function( event, handlers ) {
5541		var i, handleObj, sel, matchedHandlers, matchedSelectors,
5542			handlerQueue = [],
5543			delegateCount = handlers.delegateCount,
5544			cur = event.target;
5545
5546		// Find delegate handlers
5547		if ( delegateCount &&
5548
5549			// Support: IE <=9
5550			// Black-hole SVG <use> instance trees (trac-13180)
5551			cur.nodeType &&
5552
5553			// Support: Firefox <=42
5554			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5555			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5556			// Support: IE 11 only
5557			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5558			!( event.type === "click" && event.button >= 1 ) ) {
5559
5560			for ( ; cur !== this; cur = cur.parentNode || this ) {
5561
5562				// Don't check non-elements (#13208)
5563				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5564				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5565					matchedHandlers = [];
5566					matchedSelectors = {};
5567					for ( i = 0; i < delegateCount; i++ ) {
5568						handleObj = handlers[ i ];
5569
5570						// Don't conflict with Object.prototype properties (#13203)
5571						sel = handleObj.selector + " ";
5572
5573						if ( matchedSelectors[ sel ] === undefined ) {
5574							matchedSelectors[ sel ] = handleObj.needsContext ?
5575								jQuery( sel, this ).index( cur ) > -1 :
5576								jQuery.find( sel, this, null, [ cur ] ).length;
5577						}
5578						if ( matchedSelectors[ sel ] ) {
5579							matchedHandlers.push( handleObj );
5580						}
5581					}
5582					if ( matchedHandlers.length ) {
5583						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5584					}
5585				}
5586			}
5587		}
5588
5589		// Add the remaining (directly-bound) handlers
5590		cur = this;
5591		if ( delegateCount < handlers.length ) {
5592			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5593		}
5594
5595		return handlerQueue;
5596	},
5597
5598	addProp: function( name, hook ) {
5599		Object.defineProperty( jQuery.Event.prototype, name, {
5600			enumerable: true,
5601			configurable: true,
5602
5603			get: isFunction( hook ) ?
5604				function() {
5605					if ( this.originalEvent ) {
5606						return hook( this.originalEvent );
5607					}
5608				} :
5609				function() {
5610					if ( this.originalEvent ) {
5611						return this.originalEvent[ name ];
5612					}
5613				},
5614
5615			set: function( value ) {
5616				Object.defineProperty( this, name, {
5617					enumerable: true,
5618					configurable: true,
5619					writable: true,
5620					value: value
5621				} );
5622			}
5623		} );
5624	},
5625
5626	fix: function( originalEvent ) {
5627		return originalEvent[ jQuery.expando ] ?
5628			originalEvent :
5629			new jQuery.Event( originalEvent );
5630	},
5631
5632	special: {
5633		load: {
5634
5635			// Prevent triggered image.load events from bubbling to window.load
5636			noBubble: true
5637		},
5638		click: {
5639
5640			// Utilize native event to ensure correct state for checkable inputs
5641			setup: function( data ) {
5642
5643				// For mutual compressibility with _default, replace `this` access with a local var.
5644				// `|| data` is dead code meant only to preserve the variable through minification.
5645				var el = this || data;
5646
5647				// Claim the first handler
5648				if ( rcheckableType.test( el.type ) &&
5649					el.click && nodeName( el, "input" ) ) {
5650
5651					// dataPriv.set( el, "click", ... )
5652					leverageNative( el, "click", returnTrue );
5653				}
5654
5655				// Return false to allow normal processing in the caller
5656				return false;
5657			},
5658			trigger: function( data ) {
5659
5660				// For mutual compressibility with _default, replace `this` access with a local var.
5661				// `|| data` is dead code meant only to preserve the variable through minification.
5662				var el = this || data;
5663
5664				// Force setup before triggering a click
5665				if ( rcheckableType.test( el.type ) &&
5666					el.click && nodeName( el, "input" ) ) {
5667
5668					leverageNative( el, "click" );
5669				}
5670
5671				// Return non-false to allow normal event-path propagation
5672				return true;
5673			},
5674
5675			// For cross-browser consistency, suppress native .click() on links
5676			// Also prevent it if we're currently inside a leveraged native-event stack
5677			_default: function( event ) {
5678				var target = event.target;
5679				return rcheckableType.test( target.type ) &&
5680					target.click && nodeName( target, "input" ) &&
5681					dataPriv.get( target, "click" ) ||
5682					nodeName( target, "a" );
5683			}
5684		},
5685
5686		beforeunload: {
5687			postDispatch: function( event ) {
5688
5689				// Support: Firefox 20+
5690				// Firefox doesn't alert if the returnValue field is not set.
5691				if ( event.result !== undefined && event.originalEvent ) {
5692					event.originalEvent.returnValue = event.result;
5693				}
5694			}
5695		}
5696	}
5697};
5698
5699// Ensure the presence of an event listener that handles manually-triggered
5700// synthetic events by interrupting progress until reinvoked in response to
5701// *native* events that it fires directly, ensuring that state changes have
5702// already occurred before other listeners are invoked.
5703function leverageNative( el, type, expectSync ) {
5704
5705	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
5706	if ( !expectSync ) {
5707		if ( dataPriv.get( el, type ) === undefined ) {
5708			jQuery.event.add( el, type, returnTrue );
5709		}
5710		return;
5711	}
5712
5713	// Register the controller as a special universal handler for all event namespaces
5714	dataPriv.set( el, type, false );
5715	jQuery.event.add( el, type, {
5716		namespace: false,
5717		handler: function( event ) {
5718			var notAsync, result,
5719				saved = dataPriv.get( this, type );
5720
5721			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
5722
5723				// Interrupt processing of the outer synthetic .trigger()ed event
5724				// Saved data should be false in such cases, but might be a leftover capture object
5725				// from an async native handler (gh-4350)
5726				if ( !saved.length ) {
5727
5728					// Store arguments for use when handling the inner native event
5729					// There will always be at least one argument (an event object), so this array
5730					// will not be confused with a leftover capture object.
5731					saved = slice.call( arguments );
5732					dataPriv.set( this, type, saved );
5733
5734					// Trigger the native event and capture its result
5735					// Support: IE <=9 - 11+
5736					// focus() and blur() are asynchronous
5737					notAsync = expectSync( this, type );
5738					this[ type ]();
5739					result = dataPriv.get( this, type );
5740					if ( saved !== result || notAsync ) {
5741						dataPriv.set( this, type, false );
5742					} else {
5743						result = {};
5744					}
5745					if ( saved !== result ) {
5746
5747						// Cancel the outer synthetic event
5748						event.stopImmediatePropagation();
5749						event.preventDefault();
5750
5751						// Support: Chrome 86+
5752						// In Chrome, if an element having a focusout handler is blurred by
5753						// clicking outside of it, it invokes the handler synchronously. If
5754						// that handler calls `.remove()` on the element, the data is cleared,
5755						// leaving `result` undefined. We need to guard against this.
5756						return result && result.value;
5757					}
5758
5759				// If this is an inner synthetic event for an event with a bubbling surrogate
5760				// (focus or blur), assume that the surrogate already propagated from triggering the
5761				// native event and prevent that from happening again here.
5762				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
5763				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
5764				// less bad than duplication.
5765				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
5766					event.stopPropagation();
5767				}
5768
5769			// If this is a native event triggered above, everything is now in order
5770			// Fire an inner synthetic event with the original arguments
5771			} else if ( saved.length ) {
5772
5773				// ...and capture the result
5774				dataPriv.set( this, type, {
5775					value: jQuery.event.trigger(
5776
5777						// Support: IE <=9 - 11+
5778						// Extend with the prototype to reset the above stopImmediatePropagation()
5779						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
5780						saved.slice( 1 ),
5781						this
5782					)
5783				} );
5784
5785				// Abort handling of the native event
5786				event.stopImmediatePropagation();
5787			}
5788		}
5789	} );
5790}
5791
5792jQuery.removeEvent = function( elem, type, handle ) {
5793
5794	// This "if" is needed for plain objects
5795	if ( elem.removeEventListener ) {
5796		elem.removeEventListener( type, handle );
5797	}
5798};
5799
5800jQuery.Event = function( src, props ) {
5801
5802	// Allow instantiation without the 'new' keyword
5803	if ( !( this instanceof jQuery.Event ) ) {
5804		return new jQuery.Event( src, props );
5805	}
5806
5807	// Event object
5808	if ( src && src.type ) {
5809		this.originalEvent = src;
5810		this.type = src.type;
5811
5812		// Events bubbling up the document may have been marked as prevented
5813		// by a handler lower down the tree; reflect the correct value.
5814		this.isDefaultPrevented = src.defaultPrevented ||
5815				src.defaultPrevented === undefined &&
5816
5817				// Support: Android <=2.3 only
5818				src.returnValue === false ?
5819			returnTrue :
5820			returnFalse;
5821
5822		// Create target properties
5823		// Support: Safari <=6 - 7 only
5824		// Target should not be a text node (#504, #13143)
5825		this.target = ( src.target && src.target.nodeType === 3 ) ?
5826			src.target.parentNode :
5827			src.target;
5828
5829		this.currentTarget = src.currentTarget;
5830		this.relatedTarget = src.relatedTarget;
5831
5832	// Event type
5833	} else {
5834		this.type = src;
5835	}
5836
5837	// Put explicitly provided properties onto the event object
5838	if ( props ) {
5839		jQuery.extend( this, props );
5840	}
5841
5842	// Create a timestamp if incoming event doesn't have one
5843	this.timeStamp = src && src.timeStamp || Date.now();
5844
5845	// Mark it as fixed
5846	this[ jQuery.expando ] = true;
5847};
5848
5849// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5850// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5851jQuery.Event.prototype = {
5852	constructor: jQuery.Event,
5853	isDefaultPrevented: returnFalse,
5854	isPropagationStopped: returnFalse,
5855	isImmediatePropagationStopped: returnFalse,
5856	isSimulated: false,
5857
5858	preventDefault: function() {
5859		var e = this.originalEvent;
5860
5861		this.isDefaultPrevented = returnTrue;
5862
5863		if ( e && !this.isSimulated ) {
5864			e.preventDefault();
5865		}
5866	},
5867	stopPropagation: function() {
5868		var e = this.originalEvent;
5869
5870		this.isPropagationStopped = returnTrue;
5871
5872		if ( e && !this.isSimulated ) {
5873			e.stopPropagation();
5874		}
5875	},
5876	stopImmediatePropagation: function() {
5877		var e = this.originalEvent;
5878
5879		this.isImmediatePropagationStopped = returnTrue;
5880
5881		if ( e && !this.isSimulated ) {
5882			e.stopImmediatePropagation();
5883		}
5884
5885		this.stopPropagation();
5886	}
5887};
5888
5889// Includes all common event props including KeyEvent and MouseEvent specific props
5890jQuery.each( {
5891	altKey: true,
5892	bubbles: true,
5893	cancelable: true,
5894	changedTouches: true,
5895	ctrlKey: true,
5896	detail: true,
5897	eventPhase: true,
5898	metaKey: true,
5899	pageX: true,
5900	pageY: true,
5901	shiftKey: true,
5902	view: true,
5903	"char": true,
5904	code: true,
5905	charCode: true,
5906	key: true,
5907	keyCode: true,
5908	button: true,
5909	buttons: true,
5910	clientX: true,
5911	clientY: true,
5912	offsetX: true,
5913	offsetY: true,
5914	pointerId: true,
5915	pointerType: true,
5916	screenX: true,
5917	screenY: true,
5918	targetTouches: true,
5919	toElement: true,
5920	touches: true,
5921	which: true
5922}, jQuery.event.addProp );
5923
5924jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
5925	jQuery.event.special[ type ] = {
5926
5927		// Utilize native event if possible so blur/focus sequence is correct
5928		setup: function() {
5929
5930			// Claim the first handler
5931			// dataPriv.set( this, "focus", ... )
5932			// dataPriv.set( this, "blur", ... )
5933			leverageNative( this, type, expectSync );
5934
5935			// Return false to allow normal processing in the caller
5936			return false;
5937		},
5938		trigger: function() {
5939
5940			// Force setup before trigger
5941			leverageNative( this, type );
5942
5943			// Return non-false to allow normal event-path propagation
5944			return true;
5945		},
5946
5947		// Suppress native focus or blur as it's already being fired
5948		// in leverageNative.
5949		_default: function() {
5950			return true;
5951		},
5952
5953		delegateType: delegateType
5954	};
5955} );
5956
5957// Create mouseenter/leave events using mouseover/out and event-time checks
5958// so that event delegation works in jQuery.
5959// Do the same for pointerenter/pointerleave and pointerover/pointerout
5960//
5961// Support: Safari 7 only
5962// Safari sends mouseenter too often; see:
5963// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5964// for the description of the bug (it existed in older Chrome versions as well).
5965jQuery.each( {
5966	mouseenter: "mouseover",
5967	mouseleave: "mouseout",
5968	pointerenter: "pointerover",
5969	pointerleave: "pointerout"
5970}, function( orig, fix ) {
5971	jQuery.event.special[ orig ] = {
5972		delegateType: fix,
5973		bindType: fix,
5974
5975		handle: function( event ) {
5976			var ret,
5977				target = this,
5978				related = event.relatedTarget,
5979				handleObj = event.handleObj;
5980
5981			// For mouseenter/leave call the handler if related is outside the target.
5982			// NB: No relatedTarget if the mouse left/entered the browser window
5983			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5984				event.type = handleObj.origType;
5985				ret = handleObj.handler.apply( this, arguments );
5986				event.type = fix;
5987			}
5988			return ret;
5989		}
5990	};
5991} );
5992
5993jQuery.fn.extend( {
5994
5995	on: function( types, selector, data, fn ) {
5996		return on( this, types, selector, data, fn );
5997	},
5998	one: function( types, selector, data, fn ) {
5999		return on( this, types, selector, data, fn, 1 );
6000	},
6001	off: function( types, selector, fn ) {
6002		var handleObj, type;
6003		if ( types && types.preventDefault && types.handleObj ) {
6004
6005			// ( event )  dispatched jQuery.Event
6006			handleObj = types.handleObj;
6007			jQuery( types.delegateTarget ).off(
6008				handleObj.namespace ?
6009					handleObj.origType + "." + handleObj.namespace :
6010					handleObj.origType,
6011				handleObj.selector,
6012				handleObj.handler
6013			);
6014			return this;
6015		}
6016		if ( typeof types === "object" ) {
6017
6018			// ( types-object [, selector] )
6019			for ( type in types ) {
6020				this.off( type, selector, types[ type ] );
6021			}
6022			return this;
6023		}
6024		if ( selector === false || typeof selector === "function" ) {
6025
6026			// ( types [, fn] )
6027			fn = selector;
6028			selector = undefined;
6029		}
6030		if ( fn === false ) {
6031			fn = returnFalse;
6032		}
6033		return this.each( function() {
6034			jQuery.event.remove( this, types, fn, selector );
6035		} );
6036	}
6037} );
6038
6039
6040var
6041
6042	// Support: IE <=10 - 11, Edge 12 - 13 only
6043	// In IE/Edge using regex groups here causes severe slowdowns.
6044	// See https://connect.microsoft.com/IE/feedback/details/1736512/
6045	rnoInnerhtml = /<script|<style|<link/i,
6046
6047	// checked="checked" or checked
6048	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
6049	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
6050
6051// Prefer a tbody over its parent table for containing new rows
6052function manipulationTarget( elem, content ) {
6053	if ( nodeName( elem, "table" ) &&
6054		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
6055
6056		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
6057	}
6058
6059	return elem;
6060}
6061
6062// Replace/restore the type attribute of script elements for safe DOM manipulation
6063function disableScript( elem ) {
6064	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
6065	return elem;
6066}
6067function restoreScript( elem ) {
6068	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
6069		elem.type = elem.type.slice( 5 );
6070	} else {
6071		elem.removeAttribute( "type" );
6072	}
6073
6074	return elem;
6075}
6076
6077function cloneCopyEvent( src, dest ) {
6078	var i, l, type, pdataOld, udataOld, udataCur, events;
6079
6080	if ( dest.nodeType !== 1 ) {
6081		return;
6082	}
6083
6084	// 1. Copy private data: events, handlers, etc.
6085	if ( dataPriv.hasData( src ) ) {
6086		pdataOld = dataPriv.get( src );
6087		events = pdataOld.events;
6088
6089		if ( events ) {
6090			dataPriv.remove( dest, "handle events" );
6091
6092			for ( type in events ) {
6093				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6094					jQuery.event.add( dest, type, events[ type ][ i ] );
6095				}
6096			}
6097		}
6098	}
6099
6100	// 2. Copy user data
6101	if ( dataUser.hasData( src ) ) {
6102		udataOld = dataUser.access( src );
6103		udataCur = jQuery.extend( {}, udataOld );
6104
6105		dataUser.set( dest, udataCur );
6106	}
6107}
6108
6109// Fix IE bugs, see support tests
6110function fixInput( src, dest ) {
6111	var nodeName = dest.nodeName.toLowerCase();
6112
6113	// Fails to persist the checked state of a cloned checkbox or radio button.
6114	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6115		dest.checked = src.checked;
6116
6117	// Fails to return the selected option to the default selected state when cloning options
6118	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6119		dest.defaultValue = src.defaultValue;
6120	}
6121}
6122
6123function domManip( collection, args, callback, ignored ) {
6124
6125	// Flatten any nested arrays
6126	args = flat( args );
6127
6128	var fragment, first, scripts, hasScripts, node, doc,
6129		i = 0,
6130		l = collection.length,
6131		iNoClone = l - 1,
6132		value = args[ 0 ],
6133		valueIsFunction = isFunction( value );
6134
6135	// We can't cloneNode fragments that contain checked, in WebKit
6136	if ( valueIsFunction ||
6137			( l > 1 && typeof value === "string" &&
6138				!support.checkClone && rchecked.test( value ) ) ) {
6139		return collection.each( function( index ) {
6140			var self = collection.eq( index );
6141			if ( valueIsFunction ) {
6142				args[ 0 ] = value.call( this, index, self.html() );
6143			}
6144			domManip( self, args, callback, ignored );
6145		} );
6146	}
6147
6148	if ( l ) {
6149		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6150		first = fragment.firstChild;
6151
6152		if ( fragment.childNodes.length === 1 ) {
6153			fragment = first;
6154		}
6155
6156		// Require either new content or an interest in ignored elements to invoke the callback
6157		if ( first || ignored ) {
6158			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6159			hasScripts = scripts.length;
6160
6161			// Use the original fragment for the last item
6162			// instead of the first because it can end up
6163			// being emptied incorrectly in certain situations (#8070).
6164			for ( ; i < l; i++ ) {
6165				node = fragment;
6166
6167				if ( i !== iNoClone ) {
6168					node = jQuery.clone( node, true, true );
6169
6170					// Keep references to cloned scripts for later restoration
6171					if ( hasScripts ) {
6172
6173						// Support: Android <=4.0 only, PhantomJS 1 only
6174						// push.apply(_, arraylike) throws on ancient WebKit
6175						jQuery.merge( scripts, getAll( node, "script" ) );
6176					}
6177				}
6178
6179				callback.call( collection[ i ], node, i );
6180			}
6181
6182			if ( hasScripts ) {
6183				doc = scripts[ scripts.length - 1 ].ownerDocument;
6184
6185				// Reenable scripts
6186				jQuery.map( scripts, restoreScript );
6187
6188				// Evaluate executable scripts on first document insertion
6189				for ( i = 0; i < hasScripts; i++ ) {
6190					node = scripts[ i ];
6191					if ( rscriptType.test( node.type || "" ) &&
6192						!dataPriv.access( node, "globalEval" ) &&
6193						jQuery.contains( doc, node ) ) {
6194
6195						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
6196
6197							// Optional AJAX dependency, but won't run scripts if not present
6198							if ( jQuery._evalUrl && !node.noModule ) {
6199								jQuery._evalUrl( node.src, {
6200									nonce: node.nonce || node.getAttribute( "nonce" )
6201								}, doc );
6202							}
6203						} else {
6204							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
6205						}
6206					}
6207				}
6208			}
6209		}
6210	}
6211
6212	return collection;
6213}
6214
6215function remove( elem, selector, keepData ) {
6216	var node,
6217		nodes = selector ? jQuery.filter( selector, elem ) : elem,
6218		i = 0;
6219
6220	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
6221		if ( !keepData && node.nodeType === 1 ) {
6222			jQuery.cleanData( getAll( node ) );
6223		}
6224
6225		if ( node.parentNode ) {
6226			if ( keepData && isAttached( node ) ) {
6227				setGlobalEval( getAll( node, "script" ) );
6228			}
6229			node.parentNode.removeChild( node );
6230		}
6231	}
6232
6233	return elem;
6234}
6235
6236jQuery.extend( {
6237	htmlPrefilter: function( html ) {
6238		return html;
6239	},
6240
6241	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6242		var i, l, srcElements, destElements,
6243			clone = elem.cloneNode( true ),
6244			inPage = isAttached( elem );
6245
6246		// Fix IE cloning issues
6247		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
6248				!jQuery.isXMLDoc( elem ) ) {
6249
6250			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
6251			destElements = getAll( clone );
6252			srcElements = getAll( elem );
6253
6254			for ( i = 0, l = srcElements.length; i < l; i++ ) {
6255				fixInput( srcElements[ i ], destElements[ i ] );
6256			}
6257		}
6258
6259		// Copy the events from the original to the clone
6260		if ( dataAndEvents ) {
6261			if ( deepDataAndEvents ) {
6262				srcElements = srcElements || getAll( elem );
6263				destElements = destElements || getAll( clone );
6264
6265				for ( i = 0, l = srcElements.length; i < l; i++ ) {
6266					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
6267				}
6268			} else {
6269				cloneCopyEvent( elem, clone );
6270			}
6271		}
6272
6273		// Preserve script evaluation history
6274		destElements = getAll( clone, "script" );
6275		if ( destElements.length > 0 ) {
6276			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6277		}
6278
6279		// Return the cloned set
6280		return clone;
6281	},
6282
6283	cleanData: function( elems ) {
6284		var data, elem, type,
6285			special = jQuery.event.special,
6286			i = 0;
6287
6288		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
6289			if ( acceptData( elem ) ) {
6290				if ( ( data = elem[ dataPriv.expando ] ) ) {
6291					if ( data.events ) {
6292						for ( type in data.events ) {
6293							if ( special[ type ] ) {
6294								jQuery.event.remove( elem, type );
6295
6296							// This is a shortcut to avoid jQuery.event.remove's overhead
6297							} else {
6298								jQuery.removeEvent( elem, type, data.handle );
6299							}
6300						}
6301					}
6302
6303					// Support: Chrome <=35 - 45+
6304					// Assign undefined instead of using delete, see Data#remove
6305					elem[ dataPriv.expando ] = undefined;
6306				}
6307				if ( elem[ dataUser.expando ] ) {
6308
6309					// Support: Chrome <=35 - 45+
6310					// Assign undefined instead of using delete, see Data#remove
6311					elem[ dataUser.expando ] = undefined;
6312				}
6313			}
6314		}
6315	}
6316} );
6317
6318jQuery.fn.extend( {
6319	detach: function( selector ) {
6320		return remove( this, selector, true );
6321	},
6322
6323	remove: function( selector ) {
6324		return remove( this, selector );
6325	},
6326
6327	text: function( value ) {
6328		return access( this, function( value ) {
6329			return value === undefined ?
6330				jQuery.text( this ) :
6331				this.empty().each( function() {
6332					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6333						this.textContent = value;
6334					}
6335				} );
6336		}, null, value, arguments.length );
6337	},
6338
6339	append: function() {
6340		return domManip( this, arguments, function( elem ) {
6341			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6342				var target = manipulationTarget( this, elem );
6343				target.appendChild( elem );
6344			}
6345		} );
6346	},
6347
6348	prepend: function() {
6349		return domManip( this, arguments, function( elem ) {
6350			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6351				var target = manipulationTarget( this, elem );
6352				target.insertBefore( elem, target.firstChild );
6353			}
6354		} );
6355	},
6356
6357	before: function() {
6358		return domManip( this, arguments, function( elem ) {
6359			if ( this.parentNode ) {
6360				this.parentNode.insertBefore( elem, this );
6361			}
6362		} );
6363	},
6364
6365	after: function() {
6366		return domManip( this, arguments, function( elem ) {
6367			if ( this.parentNode ) {
6368				this.parentNode.insertBefore( elem, this.nextSibling );
6369			}
6370		} );
6371	},
6372
6373	empty: function() {
6374		var elem,
6375			i = 0;
6376
6377		for ( ; ( elem = this[ i ] ) != null; i++ ) {
6378			if ( elem.nodeType === 1 ) {
6379
6380				// Prevent memory leaks
6381				jQuery.cleanData( getAll( elem, false ) );
6382
6383				// Remove any remaining nodes
6384				elem.textContent = "";
6385			}
6386		}
6387
6388		return this;
6389	},
6390
6391	clone: function( dataAndEvents, deepDataAndEvents ) {
6392		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6393		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6394
6395		return this.map( function() {
6396			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6397		} );
6398	},
6399
6400	html: function( value ) {
6401		return access( this, function( value ) {
6402			var elem = this[ 0 ] || {},
6403				i = 0,
6404				l = this.length;
6405
6406			if ( value === undefined && elem.nodeType === 1 ) {
6407				return elem.innerHTML;
6408			}
6409
6410			// See if we can take a shortcut and just use innerHTML
6411			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6412				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6413
6414				value = jQuery.htmlPrefilter( value );
6415
6416				try {
6417					for ( ; i < l; i++ ) {
6418						elem = this[ i ] || {};
6419
6420						// Remove element nodes and prevent memory leaks
6421						if ( elem.nodeType === 1 ) {
6422							jQuery.cleanData( getAll( elem, false ) );
6423							elem.innerHTML = value;
6424						}
6425					}
6426
6427					elem = 0;
6428
6429				// If using innerHTML throws an exception, use the fallback method
6430				} catch ( e ) {}
6431			}
6432
6433			if ( elem ) {
6434				this.empty().append( value );
6435			}
6436		}, null, value, arguments.length );
6437	},
6438
6439	replaceWith: function() {
6440		var ignored = [];
6441
6442		// Make the changes, replacing each non-ignored context element with the new content
6443		return domManip( this, arguments, function( elem ) {
6444			var parent = this.parentNode;
6445
6446			if ( jQuery.inArray( this, ignored ) < 0 ) {
6447				jQuery.cleanData( getAll( this ) );
6448				if ( parent ) {
6449					parent.replaceChild( elem, this );
6450				}
6451			}
6452
6453		// Force callback invocation
6454		}, ignored );
6455	}
6456} );
6457
6458jQuery.each( {
6459	appendTo: "append",
6460	prependTo: "prepend",
6461	insertBefore: "before",
6462	insertAfter: "after",
6463	replaceAll: "replaceWith"
6464}, function( name, original ) {
6465	jQuery.fn[ name ] = function( selector ) {
6466		var elems,
6467			ret = [],
6468			insert = jQuery( selector ),
6469			last = insert.length - 1,
6470			i = 0;
6471
6472		for ( ; i <= last; i++ ) {
6473			elems = i === last ? this : this.clone( true );
6474			jQuery( insert[ i ] )[ original ]( elems );
6475
6476			// Support: Android <=4.0 only, PhantomJS 1 only
6477			// .get() because push.apply(_, arraylike) throws on ancient WebKit
6478			push.apply( ret, elems.get() );
6479		}
6480
6481		return this.pushStack( ret );
6482	};
6483} );
6484var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6485
6486var getStyles = function( elem ) {
6487
6488		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6489		// IE throws on elements created in popups
6490		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6491		var view = elem.ownerDocument.defaultView;
6492
6493		if ( !view || !view.opener ) {
6494			view = window;
6495		}
6496
6497		return view.getComputedStyle( elem );
6498	};
6499
6500var swap = function( elem, options, callback ) {
6501	var ret, name,
6502		old = {};
6503
6504	// Remember the old values, and insert the new ones
6505	for ( name in options ) {
6506		old[ name ] = elem.style[ name ];
6507		elem.style[ name ] = options[ name ];
6508	}
6509
6510	ret = callback.call( elem );
6511
6512	// Revert the old values
6513	for ( name in options ) {
6514		elem.style[ name ] = old[ name ];
6515	}
6516
6517	return ret;
6518};
6519
6520
6521var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
6522
6523
6524
6525( function() {
6526
6527	// Executing both pixelPosition & boxSizingReliable tests require only one layout
6528	// so they're executed at the same time to save the second computation.
6529	function computeStyleTests() {
6530
6531		// This is a singleton, we need to execute it only once
6532		if ( !div ) {
6533			return;
6534		}
6535
6536		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6537			"margin-top:1px;padding:0;border:0";
6538		div.style.cssText =
6539			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6540			"margin:auto;border:1px;padding:1px;" +
6541			"width:60%;top:1%";
6542		documentElement.appendChild( container ).appendChild( div );
6543
6544		var divStyle = window.getComputedStyle( div );
6545		pixelPositionVal = divStyle.top !== "1%";
6546
6547		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6548		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
6549
6550		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6551		// Some styles come back with percentage values, even though they shouldn't
6552		div.style.right = "60%";
6553		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
6554
6555		// Support: IE 9 - 11 only
6556		// Detect misreporting of content dimensions for box-sizing:border-box elements
6557		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
6558
6559		// Support: IE 9 only
6560		// Detect overflow:scroll screwiness (gh-3699)
6561		// Support: Chrome <=64
6562		// Don't get tricked when zoom affects offsetWidth (gh-4029)
6563		div.style.position = "absolute";
6564		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
6565
6566		documentElement.removeChild( container );
6567
6568		// Nullify the div so it wouldn't be stored in the memory and
6569		// it will also be a sign that checks already performed
6570		div = null;
6571	}
6572
6573	function roundPixelMeasures( measure ) {
6574		return Math.round( parseFloat( measure ) );
6575	}
6576
6577	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6578		reliableTrDimensionsVal, reliableMarginLeftVal,
6579		container = document.createElement( "div" ),
6580		div = document.createElement( "div" );
6581
6582	// Finish early in limited (non-browser) environments
6583	if ( !div.style ) {
6584		return;
6585	}
6586
6587	// Support: IE <=9 - 11 only
6588	// Style of cloned element affects source element cloned (#8908)
6589	div.style.backgroundClip = "content-box";
6590	div.cloneNode( true ).style.backgroundClip = "";
6591	support.clearCloneStyle = div.style.backgroundClip === "content-box";
6592
6593	jQuery.extend( support, {
6594		boxSizingReliable: function() {
6595			computeStyleTests();
6596			return boxSizingReliableVal;
6597		},
6598		pixelBoxStyles: function() {
6599			computeStyleTests();
6600			return pixelBoxStylesVal;
6601		},
6602		pixelPosition: function() {
6603			computeStyleTests();
6604			return pixelPositionVal;
6605		},
6606		reliableMarginLeft: function() {
6607			computeStyleTests();
6608			return reliableMarginLeftVal;
6609		},
6610		scrollboxSize: function() {
6611			computeStyleTests();
6612			return scrollboxSizeVal;
6613		},
6614
6615		// Support: IE 9 - 11+, Edge 15 - 18+
6616		// IE/Edge misreport `getComputedStyle` of table rows with width/height
6617		// set in CSS while `offset*` properties report correct values.
6618		// Behavior in IE 9 is more subtle than in newer versions & it passes
6619		// some versions of this test; make sure not to make it pass there!
6620		//
6621		// Support: Firefox 70+
6622		// Only Firefox includes border widths
6623		// in computed dimensions. (gh-4529)
6624		reliableTrDimensions: function() {
6625			var table, tr, trChild, trStyle;
6626			if ( reliableTrDimensionsVal == null ) {
6627				table = document.createElement( "table" );
6628				tr = document.createElement( "tr" );
6629				trChild = document.createElement( "div" );
6630
6631				table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
6632				tr.style.cssText = "border:1px solid";
6633
6634				// Support: Chrome 86+
6635				// Height set through cssText does not get applied.
6636				// Computed height then comes back as 0.
6637				tr.style.height = "1px";
6638				trChild.style.height = "9px";
6639
6640				// Support: Android 8 Chrome 86+
6641				// In our bodyBackground.html iframe,
6642				// display for all div elements is set to "inline",
6643				// which causes a problem only in Android 8 Chrome 86.
6644				// Ensuring the div is display: block
6645				// gets around this issue.
6646				trChild.style.display = "block";
6647
6648				documentElement
6649					.appendChild( table )
6650					.appendChild( tr )
6651					.appendChild( trChild );
6652
6653				trStyle = window.getComputedStyle( tr );
6654				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
6655					parseInt( trStyle.borderTopWidth, 10 ) +
6656					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
6657
6658				documentElement.removeChild( table );
6659			}
6660			return reliableTrDimensionsVal;
6661		}
6662	} );
6663} )();
6664
6665
6666function curCSS( elem, name, computed ) {
6667	var width, minWidth, maxWidth, ret,
6668
6669		// Support: Firefox 51+
6670		// Retrieving style before computed somehow
6671		// fixes an issue with getting wrong values
6672		// on detached elements
6673		style = elem.style;
6674
6675	computed = computed || getStyles( elem );
6676
6677	// getPropertyValue is needed for:
6678	//   .css('filter') (IE 9 only, #12537)
6679	//   .css('--customProperty) (#3144)
6680	if ( computed ) {
6681		ret = computed.getPropertyValue( name ) || computed[ name ];
6682
6683		if ( ret === "" && !isAttached( elem ) ) {
6684			ret = jQuery.style( elem, name );
6685		}
6686
6687		// A tribute to the "awesome hack by Dean Edwards"
6688		// Android Browser returns percentage for some values,
6689		// but width seems to be reliably pixels.
6690		// This is against the CSSOM draft spec:
6691		// https://drafts.csswg.org/cssom/#resolved-values
6692		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
6693
6694			// Remember the original values
6695			width = style.width;
6696			minWidth = style.minWidth;
6697			maxWidth = style.maxWidth;
6698
6699			// Put in the new values to get a computed value out
6700			style.minWidth = style.maxWidth = style.width = ret;
6701			ret = computed.width;
6702
6703			// Revert the changed values
6704			style.width = width;
6705			style.minWidth = minWidth;
6706			style.maxWidth = maxWidth;
6707		}
6708	}
6709
6710	return ret !== undefined ?
6711
6712		// Support: IE <=9 - 11 only
6713		// IE returns zIndex value as an integer.
6714		ret + "" :
6715		ret;
6716}
6717
6718
6719function addGetHookIf( conditionFn, hookFn ) {
6720
6721	// Define the hook, we'll check on the first run if it's really needed.
6722	return {
6723		get: function() {
6724			if ( conditionFn() ) {
6725
6726				// Hook not needed (or it's not possible to use it due
6727				// to missing dependency), remove it.
6728				delete this.get;
6729				return;
6730			}
6731
6732			// Hook needed; redefine it so that the support test is not executed again.
6733			return ( this.get = hookFn ).apply( this, arguments );
6734		}
6735	};
6736}
6737
6738
6739var cssPrefixes = [ "Webkit", "Moz", "ms" ],
6740	emptyStyle = document.createElement( "div" ).style,
6741	vendorProps = {};
6742
6743// Return a vendor-prefixed property or undefined
6744function vendorPropName( name ) {
6745
6746	// Check for vendor prefixed names
6747	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6748		i = cssPrefixes.length;
6749
6750	while ( i-- ) {
6751		name = cssPrefixes[ i ] + capName;
6752		if ( name in emptyStyle ) {
6753			return name;
6754		}
6755	}
6756}
6757
6758// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
6759function finalPropName( name ) {
6760	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
6761
6762	if ( final ) {
6763		return final;
6764	}
6765	if ( name in emptyStyle ) {
6766		return name;
6767	}
6768	return vendorProps[ name ] = vendorPropName( name ) || name;
6769}
6770
6771
6772var
6773
6774	// Swappable if display is none or starts with table
6775	// except "table", "table-cell", or "table-caption"
6776	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6777	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6778	rcustomProp = /^--/,
6779	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6780	cssNormalTransform = {
6781		letterSpacing: "0",
6782		fontWeight: "400"
6783	};
6784
6785function setPositiveNumber( _elem, value, subtract ) {
6786
6787	// Any relative (+/-) values have already been
6788	// normalized at this point
6789	var matches = rcssNum.exec( value );
6790	return matches ?
6791
6792		// Guard against undefined "subtract", e.g., when used as in cssHooks
6793		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6794		value;
6795}
6796
6797function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
6798	var i = dimension === "width" ? 1 : 0,
6799		extra = 0,
6800		delta = 0;
6801
6802	// Adjustment may not be necessary
6803	if ( box === ( isBorderBox ? "border" : "content" ) ) {
6804		return 0;
6805	}
6806
6807	for ( ; i < 4; i += 2 ) {
6808
6809		// Both box models exclude margin
6810		if ( box === "margin" ) {
6811			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
6812		}
6813
6814		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6815		if ( !isBorderBox ) {
6816
6817			// Add padding
6818			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6819
6820			// For "border" or "margin", add border
6821			if ( box !== "padding" ) {
6822				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6823
6824			// But still keep track of it otherwise
6825			} else {
6826				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6827			}
6828
6829		// If we get here with a border-box (content + padding + border), we're seeking "content" or
6830		// "padding" or "margin"
6831		} else {
6832
6833			// For "content", subtract padding
6834			if ( box === "content" ) {
6835				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6836			}
6837
6838			// For "content" or "padding", subtract border
6839			if ( box !== "margin" ) {
6840				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6841			}
6842		}
6843	}
6844
6845	// Account for positive content-box scroll gutter when requested by providing computedVal
6846	if ( !isBorderBox && computedVal >= 0 ) {
6847
6848		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6849		// Assuming integer scroll gutter, subtract the rest and round down
6850		delta += Math.max( 0, Math.ceil(
6851			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
6852			computedVal -
6853			delta -
6854			extra -
6855			0.5
6856
6857		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
6858		// Use an explicit zero to avoid NaN (gh-3964)
6859		) ) || 0;
6860	}
6861
6862	return delta;
6863}
6864
6865function getWidthOrHeight( elem, dimension, extra ) {
6866
6867	// Start with computed style
6868	var styles = getStyles( elem ),
6869
6870		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
6871		// Fake content-box until we know it's needed to know the true value.
6872		boxSizingNeeded = !support.boxSizingReliable() || extra,
6873		isBorderBox = boxSizingNeeded &&
6874			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6875		valueIsBorderBox = isBorderBox,
6876
6877		val = curCSS( elem, dimension, styles ),
6878		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
6879
6880	// Support: Firefox <=54
6881	// Return a confounding non-pixel value or feign ignorance, as appropriate.
6882	if ( rnumnonpx.test( val ) ) {
6883		if ( !extra ) {
6884			return val;
6885		}
6886		val = "auto";
6887	}
6888
6889
6890	// Support: IE 9 - 11 only
6891	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
6892	// In those cases, the computed value can be trusted to be border-box.
6893	if ( ( !support.boxSizingReliable() && isBorderBox ||
6894
6895		// Support: IE 10 - 11+, Edge 15 - 18+
6896		// IE/Edge misreport `getComputedStyle` of table rows with width/height
6897		// set in CSS while `offset*` properties report correct values.
6898		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
6899		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
6900
6901		// Fall back to offsetWidth/offsetHeight when value is "auto"
6902		// This happens for inline elements with no explicit setting (gh-3571)
6903		val === "auto" ||
6904
6905		// Support: Android <=4.1 - 4.3 only
6906		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6907		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
6908
6909		// Make sure the element is visible & connected
6910		elem.getClientRects().length ) {
6911
6912		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6913
6914		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
6915		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
6916		// retrieved value as a content box dimension.
6917		valueIsBorderBox = offsetProp in elem;
6918		if ( valueIsBorderBox ) {
6919			val = elem[ offsetProp ];
6920		}
6921	}
6922
6923	// Normalize "" and auto
6924	val = parseFloat( val ) || 0;
6925
6926	// Adjust for the element's box model
6927	return ( val +
6928		boxModelAdjustment(
6929			elem,
6930			dimension,
6931			extra || ( isBorderBox ? "border" : "content" ),
6932			valueIsBorderBox,
6933			styles,
6934
6935			// Provide the current computed size to request scroll gutter calculation (gh-3589)
6936			val
6937		)
6938	) + "px";
6939}
6940
6941jQuery.extend( {
6942
6943	// Add in style property hooks for overriding the default
6944	// behavior of getting and setting a style property
6945	cssHooks: {
6946		opacity: {
6947			get: function( elem, computed ) {
6948				if ( computed ) {
6949
6950					// We should always get a number back from opacity
6951					var ret = curCSS( elem, "opacity" );
6952					return ret === "" ? "1" : ret;
6953				}
6954			}
6955		}
6956	},
6957
6958	// Don't automatically add "px" to these possibly-unitless properties
6959	cssNumber: {
6960		"animationIterationCount": true,
6961		"columnCount": true,
6962		"fillOpacity": true,
6963		"flexGrow": true,
6964		"flexShrink": true,
6965		"fontWeight": true,
6966		"gridArea": true,
6967		"gridColumn": true,
6968		"gridColumnEnd": true,
6969		"gridColumnStart": true,
6970		"gridRow": true,
6971		"gridRowEnd": true,
6972		"gridRowStart": true,
6973		"lineHeight": true,
6974		"opacity": true,
6975		"order": true,
6976		"orphans": true,
6977		"widows": true,
6978		"zIndex": true,
6979		"zoom": true
6980	},
6981
6982	// Add in properties whose names you wish to fix before
6983	// setting or getting the value
6984	cssProps: {},
6985
6986	// Get and set the style property on a DOM Node
6987	style: function( elem, name, value, extra ) {
6988
6989		// Don't set styles on text and comment nodes
6990		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6991			return;
6992		}
6993
6994		// Make sure that we're working with the right name
6995		var ret, type, hooks,
6996			origName = camelCase( name ),
6997			isCustomProp = rcustomProp.test( name ),
6998			style = elem.style;
6999
7000		// Make sure that we're working with the right name. We don't
7001		// want to query the value if it is a CSS custom property
7002		// since they are user-defined.
7003		if ( !isCustomProp ) {
7004			name = finalPropName( origName );
7005		}
7006
7007		// Gets hook for the prefixed version, then unprefixed version
7008		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7009
7010		// Check if we're setting a value
7011		if ( value !== undefined ) {
7012			type = typeof value;
7013
7014			// Convert "+=" or "-=" to relative numbers (#7345)
7015			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7016				value = adjustCSS( elem, name, ret );
7017
7018				// Fixes bug #9237
7019				type = "number";
7020			}
7021
7022			// Make sure that null and NaN values aren't set (#7116)
7023			if ( value == null || value !== value ) {
7024				return;
7025			}
7026
7027			// If a number was passed in, add the unit (except for certain CSS properties)
7028			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
7029			// "px" to a few hardcoded values.
7030			if ( type === "number" && !isCustomProp ) {
7031				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7032			}
7033
7034			// background-* props affect original clone's values
7035			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7036				style[ name ] = "inherit";
7037			}
7038
7039			// If a hook was provided, use that value, otherwise just set the specified value
vendor: 25,692 bytes, lines 7040-8036
7040			if ( !hooks || !( "set" in hooks ) ||
7041				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7042
7043				if ( isCustomProp ) {
7044					style.setProperty( name, value );
7045				} else {
7046					style[ name ] = value;
7047				}
7048			}
7049
7050		} else {
7051
7052			// If a hook was provided get the non-computed value from there
7053			if ( hooks && "get" in hooks &&
7054				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7055
7056				return ret;
7057			}
7058
7059			// Otherwise just get the value from the style object
7060			return style[ name ];
7061		}
7062	},
7063
7064	css: function( elem, name, extra, styles ) {
7065		var val, num, hooks,
7066			origName = camelCase( name ),
7067			isCustomProp = rcustomProp.test( name );
7068
7069		// Make sure that we're working with the right name. We don't
7070		// want to modify the value if it is a CSS custom property
7071		// since they are user-defined.
7072		if ( !isCustomProp ) {
7073			name = finalPropName( origName );
7074		}
7075
7076		// Try prefixed name followed by the unprefixed name
7077		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7078
7079		// If a hook was provided get the computed value from there
7080		if ( hooks && "get" in hooks ) {
7081			val = hooks.get( elem, true, extra );
7082		}
7083
7084		// Otherwise, if a way to get the computed value exists, use that
7085		if ( val === undefined ) {
7086			val = curCSS( elem, name, styles );
7087		}
7088
7089		// Convert "normal" to computed value
7090		if ( val === "normal" && name in cssNormalTransform ) {
7091			val = cssNormalTransform[ name ];
7092		}
7093
7094		// Make numeric if forced or a qualifier was provided and val looks numeric
7095		if ( extra === "" || extra ) {
7096			num = parseFloat( val );
7097			return extra === true || isFinite( num ) ? num || 0 : val;
7098		}
7099
7100		return val;
7101	}
7102} );
7103
7104jQuery.each( [ "height", "width" ], function( _i, dimension ) {
7105	jQuery.cssHooks[ dimension ] = {
7106		get: function( elem, computed, extra ) {
7107			if ( computed ) {
7108
7109				// Certain elements can have dimension info if we invisibly show them
7110				// but it must have a current display style that would benefit
7111				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7112
7113					// Support: Safari 8+
7114					// Table columns in Safari have non-zero offsetWidth & zero
7115					// getBoundingClientRect().width unless display is changed.
7116					// Support: IE <=11 only
7117					// Running getBoundingClientRect on a disconnected node
7118					// in IE throws an error.
7119					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
7120					swap( elem, cssShow, function() {
7121						return getWidthOrHeight( elem, dimension, extra );
7122					} ) :
7123					getWidthOrHeight( elem, dimension, extra );
7124			}
7125		},
7126
7127		set: function( elem, value, extra ) {
7128			var matches,
7129				styles = getStyles( elem ),
7130
7131				// Only read styles.position if the test has a chance to fail
7132				// to avoid forcing a reflow.
7133				scrollboxSizeBuggy = !support.scrollboxSize() &&
7134					styles.position === "absolute",
7135
7136				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
7137				boxSizingNeeded = scrollboxSizeBuggy || extra,
7138				isBorderBox = boxSizingNeeded &&
7139					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7140				subtract = extra ?
7141					boxModelAdjustment(
7142						elem,
7143						dimension,
7144						extra,
7145						isBorderBox,
7146						styles
7147					) :
7148					0;
7149
7150			// Account for unreliable border-box dimensions by comparing offset* to computed and
7151			// faking a content-box to get border and padding (gh-3699)
7152			if ( isBorderBox && scrollboxSizeBuggy ) {
7153				subtract -= Math.ceil(
7154					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7155					parseFloat( styles[ dimension ] ) -
7156					boxModelAdjustment( elem, dimension, "border", false, styles ) -
7157					0.5
7158				);
7159			}
7160
7161			// Convert to pixels if value adjustment is needed
7162			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
7163				( matches[ 3 ] || "px" ) !== "px" ) {
7164
7165				elem.style[ dimension ] = value;
7166				value = jQuery.css( elem, dimension );
7167			}
7168
7169			return setPositiveNumber( elem, value, subtract );
7170		}
7171	};
7172} );
7173
7174jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7175	function( elem, computed ) {
7176		if ( computed ) {
7177			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
7178				elem.getBoundingClientRect().left -
7179					swap( elem, { marginLeft: 0 }, function() {
7180						return elem.getBoundingClientRect().left;
7181					} )
7182			) + "px";
7183		}
7184	}
7185);
7186
7187// These hooks are used by animate to expand properties
7188jQuery.each( {
7189	margin: "",
7190	padding: "",
7191	border: "Width"
7192}, function( prefix, suffix ) {
7193	jQuery.cssHooks[ prefix + suffix ] = {
7194		expand: function( value ) {
7195			var i = 0,
7196				expanded = {},
7197
7198				// Assumes a single number if not a string
7199				parts = typeof value === "string" ? value.split( " " ) : [ value ];
7200
7201			for ( ; i < 4; i++ ) {
7202				expanded[ prefix + cssExpand[ i ] + suffix ] =
7203					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7204			}
7205
7206			return expanded;
7207		}
7208	};
7209
7210	if ( prefix !== "margin" ) {
7211		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7212	}
7213} );
7214
7215jQuery.fn.extend( {
7216	css: function( name, value ) {
7217		return access( this, function( elem, name, value ) {
7218			var styles, len,
7219				map = {},
7220				i = 0;
7221
7222			if ( Array.isArray( name ) ) {
7223				styles = getStyles( elem );
7224				len = name.length;
7225
7226				for ( ; i < len; i++ ) {
7227					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7228				}
7229
7230				return map;
7231			}
7232
7233			return value !== undefined ?
7234				jQuery.style( elem, name, value ) :
7235				jQuery.css( elem, name );
7236		}, name, value, arguments.length > 1 );
7237	}
7238} );
7239
7240
7241function Tween( elem, options, prop, end, easing ) {
7242	return new Tween.prototype.init( elem, options, prop, end, easing );
7243}
7244jQuery.Tween = Tween;
7245
7246Tween.prototype = {
7247	constructor: Tween,
7248	init: function( elem, options, prop, end, easing, unit ) {
7249		this.elem = elem;
7250		this.prop = prop;
7251		this.easing = easing || jQuery.easing._default;
7252		this.options = options;
7253		this.start = this.now = this.cur();
7254		this.end = end;
7255		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7256	},
7257	cur: function() {
7258		var hooks = Tween.propHooks[ this.prop ];
7259
7260		return hooks && hooks.get ?
7261			hooks.get( this ) :
7262			Tween.propHooks._default.get( this );
7263	},
7264	run: function( percent ) {
7265		var eased,
7266			hooks = Tween.propHooks[ this.prop ];
7267
7268		if ( this.options.duration ) {
7269			this.pos = eased = jQuery.easing[ this.easing ](
7270				percent, this.options.duration * percent, 0, 1, this.options.duration
7271			);
7272		} else {
7273			this.pos = eased = percent;
7274		}
7275		this.now = ( this.end - this.start ) * eased + this.start;
7276
7277		if ( this.options.step ) {
7278			this.options.step.call( this.elem, this.now, this );
7279		}
7280
7281		if ( hooks && hooks.set ) {
7282			hooks.set( this );
7283		} else {
7284			Tween.propHooks._default.set( this );
7285		}
7286		return this;
7287	}
7288};
7289
7290Tween.prototype.init.prototype = Tween.prototype;
7291
7292Tween.propHooks = {
7293	_default: {
7294		get: function( tween ) {
7295			var result;
7296
7297			// Use a property on the element directly when it is not a DOM element,
7298			// or when there is no matching style property that exists.
7299			if ( tween.elem.nodeType !== 1 ||
7300				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7301				return tween.elem[ tween.prop ];
7302			}
7303
7304			// Passing an empty string as a 3rd parameter to .css will automatically
7305			// attempt a parseFloat and fallback to a string if the parse fails.
7306			// Simple values such as "10px" are parsed to Float;
7307			// complex values such as "rotate(1rad)" are returned as-is.
7308			result = jQuery.css( tween.elem, tween.prop, "" );
7309
7310			// Empty strings, null, undefined and "auto" are converted to 0.
7311			return !result || result === "auto" ? 0 : result;
7312		},
7313		set: function( tween ) {
7314
7315			// Use step hook for back compat.
7316			// Use cssHook if its there.
7317			// Use .style if available and use plain properties where available.
7318			if ( jQuery.fx.step[ tween.prop ] ) {
7319				jQuery.fx.step[ tween.prop ]( tween );
7320			} else if ( tween.elem.nodeType === 1 && (
7321				jQuery.cssHooks[ tween.prop ] ||
7322					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
7323				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7324			} else {
7325				tween.elem[ tween.prop ] = tween.now;
7326			}
7327		}
7328	}
7329};
7330
7331// Support: IE <=9 only
7332// Panic based approach to setting things on disconnected nodes
7333Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7334	set: function( tween ) {
7335		if ( tween.elem.nodeType && tween.elem.parentNode ) {
7336			tween.elem[ tween.prop ] = tween.now;
7337		}
7338	}
7339};
7340
7341jQuery.easing = {
7342	linear: function( p ) {
7343		return p;
7344	},
7345	swing: function( p ) {
7346		return 0.5 - Math.cos( p * Math.PI ) / 2;
7347	},
7348	_default: "swing"
7349};
7350
7351jQuery.fx = Tween.prototype.init;
7352
7353// Back compat <1.8 extension point
7354jQuery.fx.step = {};
7355
7356
7357
7358
7359var
7360	fxNow, inProgress,
7361	rfxtypes = /^(?:toggle|show|hide)$/,
7362	rrun = /queueHooks$/;
7363
7364function schedule() {
7365	if ( inProgress ) {
7366		if ( document.hidden === false && window.requestAnimationFrame ) {
7367			window.requestAnimationFrame( schedule );
7368		} else {
7369			window.setTimeout( schedule, jQuery.fx.interval );
7370		}
7371
7372		jQuery.fx.tick();
7373	}
7374}
7375
7376// Animations created synchronously will run synchronously
7377function createFxNow() {
7378	window.setTimeout( function() {
7379		fxNow = undefined;
7380	} );
7381	return ( fxNow = Date.now() );
7382}
7383
7384// Generate parameters to create a standard animation
7385function genFx( type, includeWidth ) {
7386	var which,
7387		i = 0,
7388		attrs = { height: type };
7389
7390	// If we include width, step value is 1 to do all cssExpand values,
7391	// otherwise step value is 2 to skip over Left and Right
7392	includeWidth = includeWidth ? 1 : 0;
7393	for ( ; i < 4; i += 2 - includeWidth ) {
7394		which = cssExpand[ i ];
7395		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7396	}
7397
7398	if ( includeWidth ) {
7399		attrs.opacity = attrs.width = type;
7400	}
7401
7402	return attrs;
7403}
7404
7405function createTween( value, prop, animation ) {
7406	var tween,
7407		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7408		index = 0,
7409		length = collection.length;
7410	for ( ; index < length; index++ ) {
7411		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7412
7413			// We're done with this property
7414			return tween;
7415		}
7416	}
7417}
7418
7419function defaultPrefilter( elem, props, opts ) {
7420	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
7421		isBox = "width" in props || "height" in props,
7422		anim = this,
7423		orig = {},
7424		style = elem.style,
7425		hidden = elem.nodeType && isHiddenWithinTree( elem ),
7426		dataShow = dataPriv.get( elem, "fxshow" );
7427
7428	// Queue-skipping animations hijack the fx hooks
7429	if ( !opts.queue ) {
7430		hooks = jQuery._queueHooks( elem, "fx" );
7431		if ( hooks.unqueued == null ) {
7432			hooks.unqueued = 0;
7433			oldfire = hooks.empty.fire;
7434			hooks.empty.fire = function() {
7435				if ( !hooks.unqueued ) {
7436					oldfire();
7437				}
7438			};
7439		}
7440		hooks.unqueued++;
7441
7442		anim.always( function() {
7443
7444			// Ensure the complete handler is called before this completes
7445			anim.always( function() {
7446				hooks.unqueued--;
7447				if ( !jQuery.queue( elem, "fx" ).length ) {
7448					hooks.empty.fire();
7449				}
7450			} );
7451		} );
7452	}
7453
7454	// Detect show/hide animations
7455	for ( prop in props ) {
7456		value = props[ prop ];
7457		if ( rfxtypes.test( value ) ) {
7458			delete props[ prop ];
7459			toggle = toggle || value === "toggle";
7460			if ( value === ( hidden ? "hide" : "show" ) ) {
7461
7462				// Pretend to be hidden if this is a "show" and
7463				// there is still data from a stopped show/hide
7464				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7465					hidden = true;
7466
7467				// Ignore all other no-op show/hide data
7468				} else {
7469					continue;
7470				}
7471			}
7472			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7473		}
7474	}
7475
7476	// Bail out if this is a no-op like .hide().hide()
7477	propTween = !jQuery.isEmptyObject( props );
7478	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
7479		return;
7480	}
7481
7482	// Restrict "overflow" and "display" styles during box animations
7483	if ( isBox && elem.nodeType === 1 ) {
7484
7485		// Support: IE <=9 - 11, Edge 12 - 15
7486		// Record all 3 overflow attributes because IE does not infer the shorthand
7487		// from identically-valued overflowX and overflowY and Edge just mirrors
7488		// the overflowX value there.
7489		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7490
7491		// Identify a display type, preferring old show/hide data over the CSS cascade
7492		restoreDisplay = dataShow && dataShow.display;
7493		if ( restoreDisplay == null ) {
7494			restoreDisplay = dataPriv.get( elem, "display" );
7495		}
7496		display = jQuery.css( elem, "display" );
7497		if ( display === "none" ) {
7498			if ( restoreDisplay ) {
7499				display = restoreDisplay;
7500			} else {
7501
7502				// Get nonempty value(s) by temporarily forcing visibility
7503				showHide( [ elem ], true );
7504				restoreDisplay = elem.style.display || restoreDisplay;
7505				display = jQuery.css( elem, "display" );
7506				showHide( [ elem ] );
7507			}
7508		}
7509
7510		// Animate inline elements as inline-block
7511		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
7512			if ( jQuery.css( elem, "float" ) === "none" ) {
7513
7514				// Restore the original display value at the end of pure show/hide animations
7515				if ( !propTween ) {
7516					anim.done( function() {
7517						style.display = restoreDisplay;
7518					} );
7519					if ( restoreDisplay == null ) {
7520						display = style.display;
7521						restoreDisplay = display === "none" ? "" : display;
7522					}
7523				}
7524				style.display = "inline-block";
7525			}
7526		}
7527	}
7528
7529	if ( opts.overflow ) {
7530		style.overflow = "hidden";
7531		anim.always( function() {
7532			style.overflow = opts.overflow[ 0 ];
7533			style.overflowX = opts.overflow[ 1 ];
7534			style.overflowY = opts.overflow[ 2 ];
7535		} );
7536	}
7537
7538	// Implement show/hide animations
7539	propTween = false;
7540	for ( prop in orig ) {
7541
7542		// General show/hide setup for this element animation
7543		if ( !propTween ) {
7544			if ( dataShow ) {
7545				if ( "hidden" in dataShow ) {
7546					hidden = dataShow.hidden;
7547				}
7548			} else {
7549				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
7550			}
7551
7552			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7553			if ( toggle ) {
7554				dataShow.hidden = !hidden;
7555			}
7556
7557			// Show elements before animating them
7558			if ( hidden ) {
7559				showHide( [ elem ], true );
7560			}
7561
7562			/* eslint-disable no-loop-func */
7563
7564			anim.done( function() {
7565
7566				/* eslint-enable no-loop-func */
7567
7568				// The final step of a "hide" animation is actually hiding the element
7569				if ( !hidden ) {
7570					showHide( [ elem ] );
7571				}
7572				dataPriv.remove( elem, "fxshow" );
7573				for ( prop in orig ) {
7574					jQuery.style( elem, prop, orig[ prop ] );
7575				}
7576			} );
7577		}
7578
7579		// Per-property setup
7580		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7581		if ( !( prop in dataShow ) ) {
7582			dataShow[ prop ] = propTween.start;
7583			if ( hidden ) {
7584				propTween.end = propTween.start;
7585				propTween.start = 0;
7586			}
7587		}
7588	}
7589}
7590
7591function propFilter( props, specialEasing ) {
7592	var index, name, easing, value, hooks;
7593
7594	// camelCase, specialEasing and expand cssHook pass
7595	for ( index in props ) {
7596		name = camelCase( index );
7597		easing = specialEasing[ name ];
7598		value = props[ index ];
7599		if ( Array.isArray( value ) ) {
7600			easing = value[ 1 ];
7601			value = props[ index ] = value[ 0 ];
7602		}
7603
7604		if ( index !== name ) {
7605			props[ name ] = value;
7606			delete props[ index ];
7607		}
7608
7609		hooks = jQuery.cssHooks[ name ];
7610		if ( hooks && "expand" in hooks ) {
7611			value = hooks.expand( value );
7612			delete props[ name ];
7613
7614			// Not quite $.extend, this won't overwrite existing keys.
7615			// Reusing 'index' because we have the correct "name"
7616			for ( index in value ) {
7617				if ( !( index in props ) ) {
7618					props[ index ] = value[ index ];
7619					specialEasing[ index ] = easing;
7620				}
7621			}
7622		} else {
7623			specialEasing[ name ] = easing;
7624		}
7625	}
7626}
7627
7628function Animation( elem, properties, options ) {
7629	var result,
7630		stopped,
7631		index = 0,
7632		length = Animation.prefilters.length,
7633		deferred = jQuery.Deferred().always( function() {
7634
7635			// Don't match elem in the :animated selector
7636			delete tick.elem;
7637		} ),
7638		tick = function() {
7639			if ( stopped ) {
7640				return false;
7641			}
7642			var currentTime = fxNow || createFxNow(),
7643				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7644
7645				// Support: Android 2.3 only
7646				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7647				temp = remaining / animation.duration || 0,
7648				percent = 1 - temp,
7649				index = 0,
7650				length = animation.tweens.length;
7651
7652			for ( ; index < length; index++ ) {
7653				animation.tweens[ index ].run( percent );
7654			}
7655
7656			deferred.notifyWith( elem, [ animation, percent, remaining ] );
7657
7658			// If there's more to do, yield
7659			if ( percent < 1 && length ) {
7660				return remaining;
7661			}
7662
7663			// If this was an empty animation, synthesize a final progress notification
7664			if ( !length ) {
7665				deferred.notifyWith( elem, [ animation, 1, 0 ] );
7666			}
7667
7668			// Resolve the animation and report its conclusion
7669			deferred.resolveWith( elem, [ animation ] );
7670			return false;
7671		},
7672		animation = deferred.promise( {
7673			elem: elem,
7674			props: jQuery.extend( {}, properties ),
7675			opts: jQuery.extend( true, {
7676				specialEasing: {},
7677				easing: jQuery.easing._default
7678			}, options ),
7679			originalProperties: properties,
7680			originalOptions: options,
7681			startTime: fxNow || createFxNow(),
7682			duration: options.duration,
7683			tweens: [],
7684			createTween: function( prop, end ) {
7685				var tween = jQuery.Tween( elem, animation.opts, prop, end,
7686					animation.opts.specialEasing[ prop ] || animation.opts.easing );
7687				animation.tweens.push( tween );
7688				return tween;
7689			},
7690			stop: function( gotoEnd ) {
7691				var index = 0,
7692
7693					// If we are going to the end, we want to run all the tweens
7694					// otherwise we skip this part
7695					length = gotoEnd ? animation.tweens.length : 0;
7696				if ( stopped ) {
7697					return this;
7698				}
7699				stopped = true;
7700				for ( ; index < length; index++ ) {
7701					animation.tweens[ index ].run( 1 );
7702				}
7703
7704				// Resolve when we played the last frame; otherwise, reject
7705				if ( gotoEnd ) {
7706					deferred.notifyWith( elem, [ animation, 1, 0 ] );
7707					deferred.resolveWith( elem, [ animation, gotoEnd ] );
7708				} else {
7709					deferred.rejectWith( elem, [ animation, gotoEnd ] );
7710				}
7711				return this;
7712			}
7713		} ),
7714		props = animation.props;
7715
7716	propFilter( props, animation.opts.specialEasing );
7717
7718	for ( ; index < length; index++ ) {
7719		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7720		if ( result ) {
7721			if ( isFunction( result.stop ) ) {
7722				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7723					result.stop.bind( result );
7724			}
7725			return result;
7726		}
7727	}
7728
7729	jQuery.map( props, createTween, animation );
7730
7731	if ( isFunction( animation.opts.start ) ) {
7732		animation.opts.start.call( elem, animation );
7733	}
7734
7735	// Attach callbacks from options
7736	animation
7737		.progress( animation.opts.progress )
7738		.done( animation.opts.done, animation.opts.complete )
7739		.fail( animation.opts.fail )
7740		.always( animation.opts.always );
7741
7742	jQuery.fx.timer(
7743		jQuery.extend( tick, {
7744			elem: elem,
7745			anim: animation,
7746			queue: animation.opts.queue
7747		} )
7748	);
7749
7750	return animation;
7751}
7752
7753jQuery.Animation = jQuery.extend( Animation, {
7754
7755	tweeners: {
7756		"*": [ function( prop, value ) {
7757			var tween = this.createTween( prop, value );
7758			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7759			return tween;
7760		} ]
7761	},
7762
7763	tweener: function( props, callback ) {
7764		if ( isFunction( props ) ) {
7765			callback = props;
7766			props = [ "*" ];
7767		} else {
7768			props = props.match( rnothtmlwhite );
7769		}
7770
7771		var prop,
7772			index = 0,
7773			length = props.length;
7774
7775		for ( ; index < length; index++ ) {
7776			prop = props[ index ];
7777			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7778			Animation.tweeners[ prop ].unshift( callback );
7779		}
7780	},
7781
7782	prefilters: [ defaultPrefilter ],
7783
7784	prefilter: function( callback, prepend ) {
7785		if ( prepend ) {
7786			Animation.prefilters.unshift( callback );
7787		} else {
7788			Animation.prefilters.push( callback );
7789		}
7790	}
7791} );
7792
7793jQuery.speed = function( speed, easing, fn ) {
7794	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7795		complete: fn || !fn && easing ||
7796			isFunction( speed ) && speed,
7797		duration: speed,
7798		easing: fn && easing || easing && !isFunction( easing ) && easing
7799	};
7800
7801	// Go to the end state if fx are off
7802	if ( jQuery.fx.off ) {
7803		opt.duration = 0;
7804
7805	} else {
7806		if ( typeof opt.duration !== "number" ) {
7807			if ( opt.duration in jQuery.fx.speeds ) {
7808				opt.duration = jQuery.fx.speeds[ opt.duration ];
7809
7810			} else {
7811				opt.duration = jQuery.fx.speeds._default;
7812			}
7813		}
7814	}
7815
7816	// Normalize opt.queue - true/undefined/null -> "fx"
7817	if ( opt.queue == null || opt.queue === true ) {
7818		opt.queue = "fx";
7819	}
7820
7821	// Queueing
7822	opt.old = opt.complete;
7823
7824	opt.complete = function() {
7825		if ( isFunction( opt.old ) ) {
7826			opt.old.call( this );
7827		}
7828
7829		if ( opt.queue ) {
7830			jQuery.dequeue( this, opt.queue );
7831		}
7832	};
7833
7834	return opt;
7835};
7836
7837jQuery.fn.extend( {
7838	fadeTo: function( speed, to, easing, callback ) {
7839
7840		// Show any hidden elements after setting opacity to 0
7841		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7842
7843			// Animate to the value specified
7844			.end().animate( { opacity: to }, speed, easing, callback );
7845	},
7846	animate: function( prop, speed, easing, callback ) {
7847		var empty = jQuery.isEmptyObject( prop ),
7848			optall = jQuery.speed( speed, easing, callback ),
7849			doAnimation = function() {
7850
7851				// Operate on a copy of prop so per-property easing won't be lost
7852				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7853
7854				// Empty animations, or finishing resolves immediately
7855				if ( empty || dataPriv.get( this, "finish" ) ) {
7856					anim.stop( true );
7857				}
7858			};
7859
7860		doAnimation.finish = doAnimation;
7861
7862		return empty || optall.queue === false ?
7863			this.each( doAnimation ) :
7864			this.queue( optall.queue, doAnimation );
7865	},
7866	stop: function( type, clearQueue, gotoEnd ) {
7867		var stopQueue = function( hooks ) {
7868			var stop = hooks.stop;
7869			delete hooks.stop;
7870			stop( gotoEnd );
7871		};
7872
7873		if ( typeof type !== "string" ) {
7874			gotoEnd = clearQueue;
7875			clearQueue = type;
7876			type = undefined;
7877		}
7878		if ( clearQueue ) {
7879			this.queue( type || "fx", [] );
7880		}
7881
7882		return this.each( function() {
7883			var dequeue = true,
7884				index = type != null && type + "queueHooks",
7885				timers = jQuery.timers,
7886				data = dataPriv.get( this );
7887
7888			if ( index ) {
7889				if ( data[ index ] && data[ index ].stop ) {
7890					stopQueue( data[ index ] );
7891				}
7892			} else {
7893				for ( index in data ) {
7894					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7895						stopQueue( data[ index ] );
7896					}
7897				}
7898			}
7899
7900			for ( index = timers.length; index--; ) {
7901				if ( timers[ index ].elem === this &&
7902					( type == null || timers[ index ].queue === type ) ) {
7903
7904					timers[ index ].anim.stop( gotoEnd );
7905					dequeue = false;
7906					timers.splice( index, 1 );
7907				}
7908			}
7909
7910			// Start the next in the queue if the last step wasn't forced.
7911			// Timers currently will call their complete callbacks, which
7912			// will dequeue but only if they were gotoEnd.
7913			if ( dequeue || !gotoEnd ) {
7914				jQuery.dequeue( this, type );
7915			}
7916		} );
7917	},
7918	finish: function( type ) {
7919		if ( type !== false ) {
7920			type = type || "fx";
7921		}
7922		return this.each( function() {
7923			var index,
7924				data = dataPriv.get( this ),
7925				queue = data[ type + "queue" ],
7926				hooks = data[ type + "queueHooks" ],
7927				timers = jQuery.timers,
7928				length = queue ? queue.length : 0;
7929
7930			// Enable finishing flag on private data
7931			data.finish = true;
7932
7933			// Empty the queue first
7934			jQuery.queue( this, type, [] );
7935
7936			if ( hooks && hooks.stop ) {
7937				hooks.stop.call( this, true );
7938			}
7939
7940			// Look for any active animations, and finish them
7941			for ( index = timers.length; index--; ) {
7942				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7943					timers[ index ].anim.stop( true );
7944					timers.splice( index, 1 );
7945				}
7946			}
7947
7948			// Look for any animations in the old queue and finish them
7949			for ( index = 0; index < length; index++ ) {
7950				if ( queue[ index ] && queue[ index ].finish ) {
7951					queue[ index ].finish.call( this );
7952				}
7953			}
7954
7955			// Turn off finishing flag
7956			delete data.finish;
7957		} );
7958	}
7959} );
7960
7961jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
7962	var cssFn = jQuery.fn[ name ];
7963	jQuery.fn[ name ] = function( speed, easing, callback ) {
7964		return speed == null || typeof speed === "boolean" ?
7965			cssFn.apply( this, arguments ) :
7966			this.animate( genFx( name, true ), speed, easing, callback );
7967	};
7968} );
7969
7970// Generate shortcuts for custom animations
7971jQuery.each( {
7972	slideDown: genFx( "show" ),
7973	slideUp: genFx( "hide" ),
7974	slideToggle: genFx( "toggle" ),
7975	fadeIn: { opacity: "show" },
7976	fadeOut: { opacity: "hide" },
7977	fadeToggle: { opacity: "toggle" }
7978}, function( name, props ) {
7979	jQuery.fn[ name ] = function( speed, easing, callback ) {
7980		return this.animate( props, speed, easing, callback );
7981	};
7982} );
7983
7984jQuery.timers = [];
7985jQuery.fx.tick = function() {
7986	var timer,
7987		i = 0,
7988		timers = jQuery.timers;
7989
7990	fxNow = Date.now();
7991
7992	for ( ; i < timers.length; i++ ) {
7993		timer = timers[ i ];
7994
7995		// Run the timer and safely remove it when done (allowing for external removal)
7996		if ( !timer() && timers[ i ] === timer ) {
7997			timers.splice( i--, 1 );
7998		}
7999	}
8000
8001	if ( !timers.length ) {
8002		jQuery.fx.stop();
8003	}
8004	fxNow = undefined;
8005};
8006
8007jQuery.fx.timer = function( timer ) {
8008	jQuery.timers.push( timer );
8009	jQuery.fx.start();
8010};
8011
8012jQuery.fx.interval = 13;
8013jQuery.fx.start = function() {
8014	if ( inProgress ) {
8015		return;
8016	}
8017
8018	inProgress = true;
8019	schedule();
8020};
8021
8022jQuery.fx.stop = function() {
8023	inProgress = null;
8024};
8025
8026jQuery.fx.speeds = {
8027	slow: 600,
8028	fast: 200,
8029
8030	// Default speed
8031	_default: 400
8032};
8033
8034
8035// Based off of the plugin by Clint Helfers, with permission.
8036// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
vendor: 21,001 bytes, lines 8037-8905
8037jQuery.fn.delay = function( time, type ) {
8038	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8039	type = type || "fx";
8040
8041	return this.queue( type, function( next, hooks ) {
8042		var timeout = window.setTimeout( next, time );
8043		hooks.stop = function() {
8044			window.clearTimeout( timeout );
8045		};
8046	} );
8047};
8048
8049
8050( function() {
8051	var input = document.createElement( "input" ),
8052		select = document.createElement( "select" ),
8053		opt = select.appendChild( document.createElement( "option" ) );
8054
8055	input.type = "checkbox";
8056
8057	// Support: Android <=4.3 only
8058	// Default value for a checkbox should be "on"
8059	support.checkOn = input.value !== "";
8060
8061	// Support: IE <=11 only
8062	// Must access selectedIndex to make default options select
8063	support.optSelected = opt.selected;
8064
8065	// Support: IE <=11 only
8066	// An input loses its value after becoming a radio
8067	input = document.createElement( "input" );
8068	input.value = "t";
8069	input.type = "radio";
8070	support.radioValue = input.value === "t";
8071} )();
8072
8073
8074var boolHook,
8075	attrHandle = jQuery.expr.attrHandle;
8076
8077jQuery.fn.extend( {
8078	attr: function( name, value ) {
8079		return access( this, jQuery.attr, name, value, arguments.length > 1 );
8080	},
8081
8082	removeAttr: function( name ) {
8083		return this.each( function() {
8084			jQuery.removeAttr( this, name );
8085		} );
8086	}
8087} );
8088
8089jQuery.extend( {
8090	attr: function( elem, name, value ) {
8091		var ret, hooks,
8092			nType = elem.nodeType;
8093
8094		// Don't get/set attributes on text, comment and attribute nodes
8095		if ( nType === 3 || nType === 8 || nType === 2 ) {
8096			return;
8097		}
8098
8099		// Fallback to prop when attributes are not supported
8100		if ( typeof elem.getAttribute === "undefined" ) {
8101			return jQuery.prop( elem, name, value );
8102		}
8103
8104		// Attribute hooks are determined by the lowercase version
8105		// Grab necessary hook if one is defined
8106		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8107			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
8108				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
8109		}
8110
8111		if ( value !== undefined ) {
8112			if ( value === null ) {
8113				jQuery.removeAttr( elem, name );
8114				return;
8115			}
8116
8117			if ( hooks && "set" in hooks &&
8118				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8119				return ret;
8120			}
8121
8122			elem.setAttribute( name, value + "" );
8123			return value;
8124		}
8125
8126		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8127			return ret;
8128		}
8129
8130		ret = jQuery.find.attr( elem, name );
8131
8132		// Non-existent attributes return null, we normalize to undefined
8133		return ret == null ? undefined : ret;
8134	},
8135
8136	attrHooks: {
8137		type: {
8138			set: function( elem, value ) {
8139				if ( !support.radioValue && value === "radio" &&
8140					nodeName( elem, "input" ) ) {
8141					var val = elem.value;
8142					elem.setAttribute( "type", value );
8143					if ( val ) {
8144						elem.value = val;
8145					}
8146					return value;
8147				}
8148			}
8149		}
8150	},
8151
8152	removeAttr: function( elem, value ) {
8153		var name,
8154			i = 0,
8155
8156			// Attribute names can contain non-HTML whitespace characters
8157			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8158			attrNames = value && value.match( rnothtmlwhite );
8159
8160		if ( attrNames && elem.nodeType === 1 ) {
8161			while ( ( name = attrNames[ i++ ] ) ) {
8162				elem.removeAttribute( name );
8163			}
8164		}
8165	}
8166} );
8167
8168// Hooks for boolean attributes
8169boolHook = {
8170	set: function( elem, value, name ) {
8171		if ( value === false ) {
8172
8173			// Remove boolean attributes when set to false
8174			jQuery.removeAttr( elem, name );
8175		} else {
8176			elem.setAttribute( name, name );
8177		}
8178		return name;
8179	}
8180};
8181
8182jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
8183	var getter = attrHandle[ name ] || jQuery.find.attr;
8184
8185	attrHandle[ name ] = function( elem, name, isXML ) {
8186		var ret, handle,
8187			lowercaseName = name.toLowerCase();
8188
8189		if ( !isXML ) {
8190
8191			// Avoid an infinite loop by temporarily removing this function from the getter
8192			handle = attrHandle[ lowercaseName ];
8193			attrHandle[ lowercaseName ] = ret;
8194			ret = getter( elem, name, isXML ) != null ?
8195				lowercaseName :
8196				null;
8197			attrHandle[ lowercaseName ] = handle;
8198		}
8199		return ret;
8200	};
8201} );
8202
8203
8204
8205
8206var rfocusable = /^(?:input|select|textarea|button)$/i,
8207	rclickable = /^(?:a|area)$/i;
8208
8209jQuery.fn.extend( {
8210	prop: function( name, value ) {
8211		return access( this, jQuery.prop, name, value, arguments.length > 1 );
8212	},
8213
8214	removeProp: function( name ) {
8215		return this.each( function() {
8216			delete this[ jQuery.propFix[ name ] || name ];
8217		} );
8218	}
8219} );
8220
8221jQuery.extend( {
8222	prop: function( elem, name, value ) {
8223		var ret, hooks,
8224			nType = elem.nodeType;
8225
8226		// Don't get/set properties on text, comment and attribute nodes
8227		if ( nType === 3 || nType === 8 || nType === 2 ) {
8228			return;
8229		}
8230
8231		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8232
8233			// Fix name and attach hooks
8234			name = jQuery.propFix[ name ] || name;
8235			hooks = jQuery.propHooks[ name ];
8236		}
8237
8238		if ( value !== undefined ) {
8239			if ( hooks && "set" in hooks &&
8240				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8241				return ret;
8242			}
8243
8244			return ( elem[ name ] = value );
8245		}
8246
8247		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8248			return ret;
8249		}
8250
8251		return elem[ name ];
8252	},
8253
8254	propHooks: {
8255		tabIndex: {
8256			get: function( elem ) {
8257
8258				// Support: IE <=9 - 11 only
8259				// elem.tabIndex doesn't always return the
8260				// correct value when it hasn't been explicitly set
8261				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8262				// Use proper attribute retrieval(#12072)
8263				var tabindex = jQuery.find.attr( elem, "tabindex" );
8264
8265				if ( tabindex ) {
8266					return parseInt( tabindex, 10 );
8267				}
8268
8269				if (
8270					rfocusable.test( elem.nodeName ) ||
8271					rclickable.test( elem.nodeName ) &&
8272					elem.href
8273				) {
8274					return 0;
8275				}
8276
8277				return -1;
8278			}
8279		}
8280	},
8281
8282	propFix: {
8283		"for": "htmlFor",
8284		"class": "className"
8285	}
8286} );
8287
8288// Support: IE <=11 only
8289// Accessing the selectedIndex property
8290// forces the browser to respect setting selected
8291// on the option
8292// The getter ensures a default option is selected
8293// when in an optgroup
8294// eslint rule "no-unused-expressions" is disabled for this code
8295// since it considers such accessions noop
8296if ( !support.optSelected ) {
8297	jQuery.propHooks.selected = {
8298		get: function( elem ) {
8299
8300			/* eslint no-unused-expressions: "off" */
8301
8302			var parent = elem.parentNode;
8303			if ( parent && parent.parentNode ) {
8304				parent.parentNode.selectedIndex;
8305			}
8306			return null;
8307		},
8308		set: function( elem ) {
8309
8310			/* eslint no-unused-expressions: "off" */
8311
8312			var parent = elem.parentNode;
8313			if ( parent ) {
8314				parent.selectedIndex;
8315
8316				if ( parent.parentNode ) {
8317					parent.parentNode.selectedIndex;
8318				}
8319			}
8320		}
8321	};
8322}
8323
8324jQuery.each( [
8325	"tabIndex",
8326	"readOnly",
8327	"maxLength",
8328	"cellSpacing",
8329	"cellPadding",
8330	"rowSpan",
8331	"colSpan",
8332	"useMap",
8333	"frameBorder",
8334	"contentEditable"
8335], function() {
8336	jQuery.propFix[ this.toLowerCase() ] = this;
8337} );
8338
8339
8340
8341
8342	// Strip and collapse whitespace according to HTML spec
8343	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8344	function stripAndCollapse( value ) {
8345		var tokens = value.match( rnothtmlwhite ) || [];
8346		return tokens.join( " " );
8347	}
8348
8349
8350function getClass( elem ) {
8351	return elem.getAttribute && elem.getAttribute( "class" ) || "";
8352}
8353
8354function classesToArray( value ) {
8355	if ( Array.isArray( value ) ) {
8356		return value;
8357	}
8358	if ( typeof value === "string" ) {
8359		return value.match( rnothtmlwhite ) || [];
8360	}
8361	return [];
8362}
8363
8364jQuery.fn.extend( {
8365	addClass: function( value ) {
8366		var classes, elem, cur, curValue, clazz, j, finalValue,
8367			i = 0;
8368
8369		if ( isFunction( value ) ) {
8370			return this.each( function( j ) {
8371				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8372			} );
8373		}
8374
8375		classes = classesToArray( value );
8376
8377		if ( classes.length ) {
8378			while ( ( elem = this[ i++ ] ) ) {
8379				curValue = getClass( elem );
8380				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8381
8382				if ( cur ) {
8383					j = 0;
8384					while ( ( clazz = classes[ j++ ] ) ) {
8385						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8386							cur += clazz + " ";
8387						}
8388					}
8389
8390					// Only assign if different to avoid unneeded rendering.
8391					finalValue = stripAndCollapse( cur );
8392					if ( curValue !== finalValue ) {
8393						elem.setAttribute( "class", finalValue );
8394					}
8395				}
8396			}
8397		}
8398
8399		return this;
8400	},
8401
8402	removeClass: function( value ) {
8403		var classes, elem, cur, curValue, clazz, j, finalValue,
8404			i = 0;
8405
8406		if ( isFunction( value ) ) {
8407			return this.each( function( j ) {
8408				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8409			} );
8410		}
8411
8412		if ( !arguments.length ) {
8413			return this.attr( "class", "" );
8414		}
8415
8416		classes = classesToArray( value );
8417
8418		if ( classes.length ) {
8419			while ( ( elem = this[ i++ ] ) ) {
8420				curValue = getClass( elem );
8421
8422				// This expression is here for better compressibility (see addClass)
8423				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8424
8425				if ( cur ) {
8426					j = 0;
8427					while ( ( clazz = classes[ j++ ] ) ) {
8428
8429						// Remove *all* instances
8430						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8431							cur = cur.replace( " " + clazz + " ", " " );
8432						}
8433					}
8434
8435					// Only assign if different to avoid unneeded rendering.
8436					finalValue = stripAndCollapse( cur );
8437					if ( curValue !== finalValue ) {
8438						elem.setAttribute( "class", finalValue );
8439					}
8440				}
8441			}
8442		}
8443
8444		return this;
8445	},
8446
8447	toggleClass: function( value, stateVal ) {
8448		var type = typeof value,
8449			isValidValue = type === "string" || Array.isArray( value );
8450
8451		if ( typeof stateVal === "boolean" && isValidValue ) {
8452			return stateVal ? this.addClass( value ) : this.removeClass( value );
8453		}
8454
8455		if ( isFunction( value ) ) {
8456			return this.each( function( i ) {
8457				jQuery( this ).toggleClass(
8458					value.call( this, i, getClass( this ), stateVal ),
8459					stateVal
8460				);
8461			} );
8462		}
8463
8464		return this.each( function() {
8465			var className, i, self, classNames;
8466
8467			if ( isValidValue ) {
8468
8469				// Toggle individual class names
8470				i = 0;
8471				self = jQuery( this );
8472				classNames = classesToArray( value );
8473
8474				while ( ( className = classNames[ i++ ] ) ) {
8475
8476					// Check each className given, space separated list
8477					if ( self.hasClass( className ) ) {
8478						self.removeClass( className );
8479					} else {
8480						self.addClass( className );
8481					}
8482				}
8483
8484			// Toggle whole class name
8485			} else if ( value === undefined || type === "boolean" ) {
8486				className = getClass( this );
8487				if ( className ) {
8488
8489					// Store className if set
8490					dataPriv.set( this, "__className__", className );
8491				}
8492
8493				// If the element has a class name or if we're passed `false`,
8494				// then remove the whole classname (if there was one, the above saved it).
8495				// Otherwise bring back whatever was previously saved (if anything),
8496				// falling back to the empty string if nothing was stored.
8497				if ( this.setAttribute ) {
8498					this.setAttribute( "class",
8499						className || value === false ?
8500							"" :
8501							dataPriv.get( this, "__className__" ) || ""
8502					);
8503				}
8504			}
8505		} );
8506	},
8507
8508	hasClass: function( selector ) {
8509		var className, elem,
8510			i = 0;
8511
8512		className = " " + selector + " ";
8513		while ( ( elem = this[ i++ ] ) ) {
8514			if ( elem.nodeType === 1 &&
8515				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
8516				return true;
8517			}
8518		}
8519
8520		return false;
8521	}
8522} );
8523
8524
8525
8526
8527var rreturn = /\r/g;
8528
8529jQuery.fn.extend( {
8530	val: function( value ) {
8531		var hooks, ret, valueIsFunction,
8532			elem = this[ 0 ];
8533
8534		if ( !arguments.length ) {
8535			if ( elem ) {
8536				hooks = jQuery.valHooks[ elem.type ] ||
8537					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8538
8539				if ( hooks &&
8540					"get" in hooks &&
8541					( ret = hooks.get( elem, "value" ) ) !== undefined
8542				) {
8543					return ret;
8544				}
8545
8546				ret = elem.value;
8547
8548				// Handle most common string cases
8549				if ( typeof ret === "string" ) {
8550					return ret.replace( rreturn, "" );
8551				}
8552
8553				// Handle cases where value is null/undef or number
8554				return ret == null ? "" : ret;
8555			}
8556
8557			return;
8558		}
8559
8560		valueIsFunction = isFunction( value );
8561
8562		return this.each( function( i ) {
8563			var val;
8564
8565			if ( this.nodeType !== 1 ) {
8566				return;
8567			}
8568
8569			if ( valueIsFunction ) {
8570				val = value.call( this, i, jQuery( this ).val() );
8571			} else {
8572				val = value;
8573			}
8574
8575			// Treat null/undefined as ""; convert numbers to string
8576			if ( val == null ) {
8577				val = "";
8578
8579			} else if ( typeof val === "number" ) {
8580				val += "";
8581
8582			} else if ( Array.isArray( val ) ) {
8583				val = jQuery.map( val, function( value ) {
8584					return value == null ? "" : value + "";
8585				} );
8586			}
8587
8588			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8589
8590			// If set returns undefined, fall back to normal setting
8591			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8592				this.value = val;
8593			}
8594		} );
8595	}
8596} );
8597
8598jQuery.extend( {
8599	valHooks: {
8600		option: {
8601			get: function( elem ) {
8602
8603				var val = jQuery.find.attr( elem, "value" );
8604				return val != null ?
8605					val :
8606
8607					// Support: IE <=10 - 11 only
8608					// option.text throws exceptions (#14686, #14858)
8609					// Strip and collapse whitespace
8610					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8611					stripAndCollapse( jQuery.text( elem ) );
8612			}
8613		},
8614		select: {
8615			get: function( elem ) {
8616				var value, option, i,
8617					options = elem.options,
8618					index = elem.selectedIndex,
8619					one = elem.type === "select-one",
8620					values = one ? null : [],
8621					max = one ? index + 1 : options.length;
8622
8623				if ( index < 0 ) {
8624					i = max;
8625
8626				} else {
8627					i = one ? index : 0;
8628				}
8629
8630				// Loop through all the selected options
8631				for ( ; i < max; i++ ) {
8632					option = options[ i ];
8633
8634					// Support: IE <=9 only
8635					// IE8-9 doesn't update selected after form reset (#2551)
8636					if ( ( option.selected || i === index ) &&
8637
8638							// Don't return options that are disabled or in a disabled optgroup
8639							!option.disabled &&
8640							( !option.parentNode.disabled ||
8641								!nodeName( option.parentNode, "optgroup" ) ) ) {
8642
8643						// Get the specific value for the option
8644						value = jQuery( option ).val();
8645
8646						// We don't need an array for one selects
8647						if ( one ) {
8648							return value;
8649						}
8650
8651						// Multi-Selects return an array
8652						values.push( value );
8653					}
8654				}
8655
8656				return values;
8657			},
8658
8659			set: function( elem, value ) {
8660				var optionSet, option,
8661					options = elem.options,
8662					values = jQuery.makeArray( value ),
8663					i = options.length;
8664
8665				while ( i-- ) {
8666					option = options[ i ];
8667
8668					/* eslint-disable no-cond-assign */
8669
8670					if ( option.selected =
8671						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8672					) {
8673						optionSet = true;
8674					}
8675
8676					/* eslint-enable no-cond-assign */
8677				}
8678
8679				// Force browsers to behave consistently when non-matching value is set
8680				if ( !optionSet ) {
8681					elem.selectedIndex = -1;
8682				}
8683				return values;
8684			}
8685		}
8686	}
8687} );
8688
8689// Radios and checkboxes getter/setter
8690jQuery.each( [ "radio", "checkbox" ], function() {
8691	jQuery.valHooks[ this ] = {
8692		set: function( elem, value ) {
8693			if ( Array.isArray( value ) ) {
8694				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8695			}
8696		}
8697	};
8698	if ( !support.checkOn ) {
8699		jQuery.valHooks[ this ].get = function( elem ) {
8700			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8701		};
8702	}
8703} );
8704
8705
8706
8707
8708// Return jQuery for attributes-only inclusion
8709
8710
8711support.focusin = "onfocusin" in window;
8712
8713
8714var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8715	stopPropagationCallback = function( e ) {
8716		e.stopPropagation();
8717	};
8718
8719jQuery.extend( jQuery.event, {
8720
8721	trigger: function( event, data, elem, onlyHandlers ) {
8722
8723		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
8724			eventPath = [ elem || document ],
8725			type = hasOwn.call( event, "type" ) ? event.type : event,
8726			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8727
8728		cur = lastElement = tmp = elem = elem || document;
8729
8730		// Don't do events on text and comment nodes
8731		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8732			return;
8733		}
8734
8735		// focus/blur morphs to focusin/out; ensure we're not firing them right now
8736		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8737			return;
8738		}
8739
8740		if ( type.indexOf( "." ) > -1 ) {
8741
8742			// Namespaced trigger; create a regexp to match event type in handle()
8743			namespaces = type.split( "." );
8744			type = namespaces.shift();
8745			namespaces.sort();
8746		}
8747		ontype = type.indexOf( ":" ) < 0 && "on" + type;
8748
8749		// Caller can pass in a jQuery.Event object, Object, or just an event type string
8750		event = event[ jQuery.expando ] ?
8751			event :
8752			new jQuery.Event( type, typeof event === "object" && event );
8753
8754		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8755		event.isTrigger = onlyHandlers ? 2 : 3;
8756		event.namespace = namespaces.join( "." );
8757		event.rnamespace = event.namespace ?
8758			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8759			null;
8760
8761		// Clean up the event in case it is being reused
8762		event.result = undefined;
8763		if ( !event.target ) {
8764			event.target = elem;
8765		}
8766
8767		// Clone any incoming data and prepend the event, creating the handler arg list
8768		data = data == null ?
8769			[ event ] :
8770			jQuery.makeArray( data, [ event ] );
8771
8772		// Allow special events to draw outside the lines
8773		special = jQuery.event.special[ type ] || {};
8774		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8775			return;
8776		}
8777
8778		// Determine event propagation path in advance, per W3C events spec (#9951)
8779		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8780		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
8781
8782			bubbleType = special.delegateType || type;
8783			if ( !rfocusMorph.test( bubbleType + type ) ) {
8784				cur = cur.parentNode;
8785			}
8786			for ( ; cur; cur = cur.parentNode ) {
8787				eventPath.push( cur );
8788				tmp = cur;
8789			}
8790
8791			// Only add window if we got to document (e.g., not plain obj or detached DOM)
8792			if ( tmp === ( elem.ownerDocument || document ) ) {
8793				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8794			}
8795		}
8796
8797		// Fire handlers on the event path
8798		i = 0;
8799		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8800			lastElement = cur;
8801			event.type = i > 1 ?
8802				bubbleType :
8803				special.bindType || type;
8804
8805			// jQuery handler
8806			handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
8807				dataPriv.get( cur, "handle" );
8808			if ( handle ) {
8809				handle.apply( cur, data );
8810			}
8811
8812			// Native handler
8813			handle = ontype && cur[ ontype ];
8814			if ( handle && handle.apply && acceptData( cur ) ) {
8815				event.result = handle.apply( cur, data );
8816				if ( event.result === false ) {
8817					event.preventDefault();
8818				}
8819			}
8820		}
8821		event.type = type;
8822
8823		// If nobody prevented the default action, do it now
8824		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8825
8826			if ( ( !special._default ||
8827				special._default.apply( eventPath.pop(), data ) === false ) &&
8828				acceptData( elem ) ) {
8829
8830				// Call a native DOM method on the target with the same name as the event.
8831				// Don't do default actions on window, that's where global variables be (#6170)
8832				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
8833
8834					// Don't re-trigger an onFOO event when we call its FOO() method
8835					tmp = elem[ ontype ];
8836
8837					if ( tmp ) {
8838						elem[ ontype ] = null;
8839					}
8840
8841					// Prevent re-triggering of the same event, since we already bubbled it above
8842					jQuery.event.triggered = type;
8843
8844					if ( event.isPropagationStopped() ) {
8845						lastElement.addEventListener( type, stopPropagationCallback );
8846					}
8847
8848					elem[ type ]();
8849
8850					if ( event.isPropagationStopped() ) {
8851						lastElement.removeEventListener( type, stopPropagationCallback );
8852					}
8853
8854					jQuery.event.triggered = undefined;
8855
8856					if ( tmp ) {
8857						elem[ ontype ] = tmp;
8858					}
8859				}
8860			}
8861		}
8862
8863		return event.result;
8864	},
8865
8866	// Piggyback on a donor event to simulate a different one
8867	// Used only for `focus(in | out)` events
8868	simulate: function( type, elem, event ) {
8869		var e = jQuery.extend(
8870			new jQuery.Event(),
8871			event,
8872			{
8873				type: type,
8874				isSimulated: true
8875			}
8876		);
8877
8878		jQuery.event.trigger( e, null, elem );
8879	}
8880
8881} );
8882
8883jQuery.fn.extend( {
8884
8885	trigger: function( type, data ) {
8886		return this.each( function() {
8887			jQuery.event.trigger( type, data, this );
8888		} );
8889	},
8890	triggerHandler: function( type, data ) {
8891		var elem = this[ 0 ];
8892		if ( elem ) {
8893			return jQuery.event.trigger( type, data, elem, true );
8894		}
8895	}
8896} );
8897
8898
8899// Support: Firefox <=44
8900// Firefox doesn't have focus(in | out) events
8901// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8902//
8903// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8904// focus(in | out) events fire after focus & blur events,
8905// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
vendor: 53,617 bytes, lines 8906-10931
8906// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8907if ( !support.focusin ) {
8908	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8909
8910		// Attach a single capturing handler on the document while someone wants focusin/focusout
8911		var handler = function( event ) {
8912			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8913		};
8914
8915		jQuery.event.special[ fix ] = {
8916			setup: function() {
8917
8918				// Handle: regular nodes (via `this.ownerDocument`), window
8919				// (via `this.document`) & document (via `this`).
8920				var doc = this.ownerDocument || this.document || this,
8921					attaches = dataPriv.access( doc, fix );
8922
8923				if ( !attaches ) {
8924					doc.addEventListener( orig, handler, true );
8925				}
8926				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8927			},
8928			teardown: function() {
8929				var doc = this.ownerDocument || this.document || this,
8930					attaches = dataPriv.access( doc, fix ) - 1;
8931
8932				if ( !attaches ) {
8933					doc.removeEventListener( orig, handler, true );
8934					dataPriv.remove( doc, fix );
8935
8936				} else {
8937					dataPriv.access( doc, fix, attaches );
8938				}
8939			}
8940		};
8941	} );
8942}
8943var location = window.location;
8944
8945var nonce = { guid: Date.now() };
8946
8947var rquery = ( /\?/ );
8948
8949
8950
8951// Cross-browser xml parsing
8952jQuery.parseXML = function( data ) {
8953	var xml, parserErrorElem;
8954	if ( !data || typeof data !== "string" ) {
8955		return null;
8956	}
8957
8958	// Support: IE 9 - 11 only
8959	// IE throws on parseFromString with invalid input.
8960	try {
8961		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8962	} catch ( e ) {}
8963
8964	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
8965	if ( !xml || parserErrorElem ) {
8966		jQuery.error( "Invalid XML: " + (
8967			parserErrorElem ?
8968				jQuery.map( parserErrorElem.childNodes, function( el ) {
8969					return el.textContent;
8970				} ).join( "\n" ) :
8971				data
8972		) );
8973	}
8974	return xml;
8975};
8976
8977
8978var
8979	rbracket = /\[\]$/,
8980	rCRLF = /\r?\n/g,
8981	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8982	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8983
8984function buildParams( prefix, obj, traditional, add ) {
8985	var name;
8986
8987	if ( Array.isArray( obj ) ) {
8988
8989		// Serialize array item.
8990		jQuery.each( obj, function( i, v ) {
8991			if ( traditional || rbracket.test( prefix ) ) {
8992
8993				// Treat each array item as a scalar.
8994				add( prefix, v );
8995
8996			} else {
8997
8998				// Item is non-scalar (array or object), encode its numeric index.
8999				buildParams(
9000					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
9001					v,
9002					traditional,
9003					add
9004				);
9005			}
9006		} );
9007
9008	} else if ( !traditional && toType( obj ) === "object" ) {
9009
9010		// Serialize object item.
9011		for ( name in obj ) {
9012			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9013		}
9014
9015	} else {
9016
9017		// Serialize scalar item.
9018		add( prefix, obj );
9019	}
9020}
9021
9022// Serialize an array of form elements or a set of
9023// key/values into a query string
9024jQuery.param = function( a, traditional ) {
9025	var prefix,
9026		s = [],
9027		add = function( key, valueOrFunction ) {
9028
9029			// If value is a function, invoke it and use its return value
9030			var value = isFunction( valueOrFunction ) ?
9031				valueOrFunction() :
9032				valueOrFunction;
9033
9034			s[ s.length ] = encodeURIComponent( key ) + "=" +
9035				encodeURIComponent( value == null ? "" : value );
9036		};
9037
9038	if ( a == null ) {
9039		return "";
9040	}
9041
9042	// If an array was passed in, assume that it is an array of form elements.
9043	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9044
9045		// Serialize the form elements
9046		jQuery.each( a, function() {
9047			add( this.name, this.value );
9048		} );
9049
9050	} else {
9051
9052		// If traditional, encode the "old" way (the way 1.3.2 or older
9053		// did it), otherwise encode params recursively.
9054		for ( prefix in a ) {
9055			buildParams( prefix, a[ prefix ], traditional, add );
9056		}
9057	}
9058
9059	// Return the resulting serialization
9060	return s.join( "&" );
9061};
9062
9063jQuery.fn.extend( {
9064	serialize: function() {
9065		return jQuery.param( this.serializeArray() );
9066	},
9067	serializeArray: function() {
9068		return this.map( function() {
9069
9070			// Can add propHook for "elements" to filter or add form elements
9071			var elements = jQuery.prop( this, "elements" );
9072			return elements ? jQuery.makeArray( elements ) : this;
9073		} ).filter( function() {
9074			var type = this.type;
9075
9076			// Use .is( ":disabled" ) so that fieldset[disabled] works
9077			return this.name && !jQuery( this ).is( ":disabled" ) &&
9078				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9079				( this.checked || !rcheckableType.test( type ) );
9080		} ).map( function( _i, elem ) {
9081			var val = jQuery( this ).val();
9082
9083			if ( val == null ) {
9084				return null;
9085			}
9086
9087			if ( Array.isArray( val ) ) {
9088				return jQuery.map( val, function( val ) {
9089					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9090				} );
9091			}
9092
9093			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9094		} ).get();
9095	}
9096} );
9097
9098
9099var
9100	r20 = /%20/g,
9101	rhash = /#.*$/,
9102	rantiCache = /([?&])_=[^&]*/,
9103	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
9104
9105	// #7653, #8125, #8152: local protocol detection
9106	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9107	rnoContent = /^(?:GET|HEAD)$/,
9108	rprotocol = /^\/\//,
9109
9110	/* Prefilters
9111	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9112	 * 2) These are called:
9113	 *    - BEFORE asking for a transport
9114	 *    - AFTER param serialization (s.data is a string if s.processData is true)
9115	 * 3) key is the dataType
9116	 * 4) the catchall symbol "*" can be used
9117	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9118	 */
9119	prefilters = {},
9120
9121	/* Transports bindings
9122	 * 1) key is the dataType
9123	 * 2) the catchall symbol "*" can be used
9124	 * 3) selection will start with transport dataType and THEN go to "*" if needed
9125	 */
9126	transports = {},
9127
9128	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9129	allTypes = "*/".concat( "*" ),
9130
9131	// Anchor tag for parsing the document origin
9132	originAnchor = document.createElement( "a" );
9133
9134originAnchor.href = location.href;
9135
9136// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9137function addToPrefiltersOrTransports( structure ) {
9138
9139	// dataTypeExpression is optional and defaults to "*"
9140	return function( dataTypeExpression, func ) {
9141
9142		if ( typeof dataTypeExpression !== "string" ) {
9143			func = dataTypeExpression;
9144			dataTypeExpression = "*";
9145		}
9146
9147		var dataType,
9148			i = 0,
9149			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
9150
9151		if ( isFunction( func ) ) {
9152
9153			// For each dataType in the dataTypeExpression
9154			while ( ( dataType = dataTypes[ i++ ] ) ) {
9155
9156				// Prepend if requested
9157				if ( dataType[ 0 ] === "+" ) {
9158					dataType = dataType.slice( 1 ) || "*";
9159					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9160
9161				// Otherwise append
9162				} else {
9163					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9164				}
9165			}
9166		}
9167	};
9168}
9169
9170// Base inspection function for prefilters and transports
9171function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9172
9173	var inspected = {},
9174		seekingTransport = ( structure === transports );
9175
9176	function inspect( dataType ) {
9177		var selected;
9178		inspected[ dataType ] = true;
9179		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9180			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9181			if ( typeof dataTypeOrTransport === "string" &&
9182				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9183
9184				options.dataTypes.unshift( dataTypeOrTransport );
9185				inspect( dataTypeOrTransport );
9186				return false;
9187			} else if ( seekingTransport ) {
9188				return !( selected = dataTypeOrTransport );
9189			}
9190		} );
9191		return selected;
9192	}
9193
9194	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9195}
9196
9197// A special extend for ajax options
9198// that takes "flat" options (not to be deep extended)
9199// Fixes #9887
9200function ajaxExtend( target, src ) {
9201	var key, deep,
9202		flatOptions = jQuery.ajaxSettings.flatOptions || {};
9203
9204	for ( key in src ) {
9205		if ( src[ key ] !== undefined ) {
9206			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9207		}
9208	}
9209	if ( deep ) {
9210		jQuery.extend( true, target, deep );
9211	}
9212
9213	return target;
9214}
9215
9216/* Handles responses to an ajax request:
9217 * - finds the right dataType (mediates between content-type and expected dataType)
9218 * - returns the corresponding response
9219 */
9220function ajaxHandleResponses( s, jqXHR, responses ) {
9221
9222	var ct, type, finalDataType, firstDataType,
9223		contents = s.contents,
9224		dataTypes = s.dataTypes;
9225
9226	// Remove auto dataType and get content-type in the process
9227	while ( dataTypes[ 0 ] === "*" ) {
9228		dataTypes.shift();
9229		if ( ct === undefined ) {
9230			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9231		}
9232	}
9233
9234	// Check if we're dealing with a known content-type
9235	if ( ct ) {
9236		for ( type in contents ) {
9237			if ( contents[ type ] && contents[ type ].test( ct ) ) {
9238				dataTypes.unshift( type );
9239				break;
9240			}
9241		}
9242	}
9243
9244	// Check to see if we have a response for the expected dataType
9245	if ( dataTypes[ 0 ] in responses ) {
9246		finalDataType = dataTypes[ 0 ];
9247	} else {
9248
9249		// Try convertible dataTypes
9250		for ( type in responses ) {
9251			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9252				finalDataType = type;
9253				break;
9254			}
9255			if ( !firstDataType ) {
9256				firstDataType = type;
9257			}
9258		}
9259
9260		// Or just use first one
9261		finalDataType = finalDataType || firstDataType;
9262	}
9263
9264	// If we found a dataType
9265	// We add the dataType to the list if needed
9266	// and return the corresponding response
9267	if ( finalDataType ) {
9268		if ( finalDataType !== dataTypes[ 0 ] ) {
9269			dataTypes.unshift( finalDataType );
9270		}
9271		return responses[ finalDataType ];
9272	}
9273}
9274
9275/* Chain conversions given the request and the original response
9276 * Also sets the responseXXX fields on the jqXHR instance
9277 */
9278function ajaxConvert( s, response, jqXHR, isSuccess ) {
9279	var conv2, current, conv, tmp, prev,
9280		converters = {},
9281
9282		// Work with a copy of dataTypes in case we need to modify it for conversion
9283		dataTypes = s.dataTypes.slice();
9284
9285	// Create converters map with lowercased keys
9286	if ( dataTypes[ 1 ] ) {
9287		for ( conv in s.converters ) {
9288			converters[ conv.toLowerCase() ] = s.converters[ conv ];
9289		}
9290	}
9291
9292	current = dataTypes.shift();
9293
9294	// Convert to each sequential dataType
9295	while ( current ) {
9296
9297		if ( s.responseFields[ current ] ) {
9298			jqXHR[ s.responseFields[ current ] ] = response;
9299		}
9300
9301		// Apply the dataFilter if provided
9302		if ( !prev && isSuccess && s.dataFilter ) {
9303			response = s.dataFilter( response, s.dataType );
9304		}
9305
9306		prev = current;
9307		current = dataTypes.shift();
9308
9309		if ( current ) {
9310
9311			// There's only work to do if current dataType is non-auto
9312			if ( current === "*" ) {
9313
9314				current = prev;
9315
9316			// Convert response if prev dataType is non-auto and differs from current
9317			} else if ( prev !== "*" && prev !== current ) {
9318
9319				// Seek a direct converter
9320				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9321
9322				// If none found, seek a pair
9323				if ( !conv ) {
9324					for ( conv2 in converters ) {
9325
9326						// If conv2 outputs current
9327						tmp = conv2.split( " " );
9328						if ( tmp[ 1 ] === current ) {
9329
9330							// If prev can be converted to accepted input
9331							conv = converters[ prev + " " + tmp[ 0 ] ] ||
9332								converters[ "* " + tmp[ 0 ] ];
9333							if ( conv ) {
9334
9335								// Condense equivalence converters
9336								if ( conv === true ) {
9337									conv = converters[ conv2 ];
9338
9339								// Otherwise, insert the intermediate dataType
9340								} else if ( converters[ conv2 ] !== true ) {
9341									current = tmp[ 0 ];
9342									dataTypes.unshift( tmp[ 1 ] );
9343								}
9344								break;
9345							}
9346						}
9347					}
9348				}
9349
9350				// Apply converter (if not an equivalence)
9351				if ( conv !== true ) {
9352
9353					// Unless errors are allowed to bubble, catch and return them
9354					if ( conv && s.throws ) {
9355						response = conv( response );
9356					} else {
9357						try {
9358							response = conv( response );
9359						} catch ( e ) {
9360							return {
9361								state: "parsererror",
9362								error: conv ? e : "No conversion from " + prev + " to " + current
9363							};
9364						}
9365					}
9366				}
9367			}
9368		}
9369	}
9370
9371	return { state: "success", data: response };
9372}
9373
9374jQuery.extend( {
9375
9376	// Counter for holding the number of active queries
9377	active: 0,
9378
9379	// Last-Modified header cache for next request
9380	lastModified: {},
9381	etag: {},
9382
9383	ajaxSettings: {
9384		url: location.href,
9385		type: "GET",
9386		isLocal: rlocalProtocol.test( location.protocol ),
9387		global: true,
9388		processData: true,
9389		async: true,
9390		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9391
9392		/*
9393		timeout: 0,
9394		data: null,
9395		dataType: null,
9396		username: null,
9397		password: null,
9398		cache: null,
9399		throws: false,
9400		traditional: false,
9401		headers: {},
9402		*/
9403
9404		accepts: {
9405			"*": allTypes,
9406			text: "text/plain",
9407			html: "text/html",
9408			xml: "application/xml, text/xml",
9409			json: "application/json, text/javascript"
9410		},
9411
9412		contents: {
9413			xml: /\bxml\b/,
9414			html: /\bhtml/,
9415			json: /\bjson\b/
9416		},
9417
9418		responseFields: {
9419			xml: "responseXML",
9420			text: "responseText",
9421			json: "responseJSON"
9422		},
9423
9424		// Data converters
9425		// Keys separate source (or catchall "*") and destination types with a single space
9426		converters: {
9427
9428			// Convert anything to text
9429			"* text": String,
9430
9431			// Text to html (true = no transformation)
9432			"text html": true,
9433
9434			// Evaluate text as a json expression
9435			"text json": JSON.parse,
9436
9437			// Parse text as xml
9438			"text xml": jQuery.parseXML
9439		},
9440
9441		// For options that shouldn't be deep extended:
9442		// you can add your own custom options here if
9443		// and when you create one that shouldn't be
9444		// deep extended (see ajaxExtend)
9445		flatOptions: {
9446			url: true,
9447			context: true
9448		}
9449	},
9450
9451	// Creates a full fledged settings object into target
9452	// with both ajaxSettings and settings fields.
9453	// If target is omitted, writes into ajaxSettings.
9454	ajaxSetup: function( target, settings ) {
9455		return settings ?
9456
9457			// Building a settings object
9458			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9459
9460			// Extending ajaxSettings
9461			ajaxExtend( jQuery.ajaxSettings, target );
9462	},
9463
9464	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9465	ajaxTransport: addToPrefiltersOrTransports( transports ),
9466
9467	// Main method
9468	ajax: function( url, options ) {
9469
9470		// If url is an object, simulate pre-1.5 signature
9471		if ( typeof url === "object" ) {
9472			options = url;
9473			url = undefined;
9474		}
9475
9476		// Force options to be an object
9477		options = options || {};
9478
9479		var transport,
9480
9481			// URL without anti-cache param
9482			cacheURL,
9483
9484			// Response headers
9485			responseHeadersString,
9486			responseHeaders,
9487
9488			// timeout handle
9489			timeoutTimer,
9490
9491			// Url cleanup var
9492			urlAnchor,
9493
9494			// Request state (becomes false upon send and true upon completion)
9495			completed,
9496
9497			// To know if global events are to be dispatched
9498			fireGlobals,
9499
9500			// Loop variable
9501			i,
9502
9503			// uncached part of the url
9504			uncached,
9505
9506			// Create the final options object
9507			s = jQuery.ajaxSetup( {}, options ),
9508
9509			// Callbacks context
9510			callbackContext = s.context || s,
9511
9512			// Context for global events is callbackContext if it is a DOM node or jQuery collection
9513			globalEventContext = s.context &&
9514				( callbackContext.nodeType || callbackContext.jquery ) ?
9515				jQuery( callbackContext ) :
9516				jQuery.event,
9517
9518			// Deferreds
9519			deferred = jQuery.Deferred(),
9520			completeDeferred = jQuery.Callbacks( "once memory" ),
9521
9522			// Status-dependent callbacks
9523			statusCode = s.statusCode || {},
9524
9525			// Headers (they are sent all at once)
9526			requestHeaders = {},
9527			requestHeadersNames = {},
9528
9529			// Default abort message
9530			strAbort = "canceled",
9531
9532			// Fake xhr
9533			jqXHR = {
9534				readyState: 0,
9535
9536				// Builds headers hashtable if needed
9537				getResponseHeader: function( key ) {
9538					var match;
9539					if ( completed ) {
9540						if ( !responseHeaders ) {
9541							responseHeaders = {};
9542							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9543								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
9544									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
9545										.concat( match[ 2 ] );
9546							}
9547						}
9548						match = responseHeaders[ key.toLowerCase() + " " ];
9549					}
9550					return match == null ? null : match.join( ", " );
9551				},
9552
9553				// Raw string
9554				getAllResponseHeaders: function() {
9555					return completed ? responseHeadersString : null;
9556				},
9557
9558				// Caches the header
9559				setRequestHeader: function( name, value ) {
9560					if ( completed == null ) {
9561						name = requestHeadersNames[ name.toLowerCase() ] =
9562							requestHeadersNames[ name.toLowerCase() ] || name;
9563						requestHeaders[ name ] = value;
9564					}
9565					return this;
9566				},
9567
9568				// Overrides response content-type header
9569				overrideMimeType: function( type ) {
9570					if ( completed == null ) {
9571						s.mimeType = type;
9572					}
9573					return this;
9574				},
9575
9576				// Status-dependent callbacks
9577				statusCode: function( map ) {
9578					var code;
9579					if ( map ) {
9580						if ( completed ) {
9581
9582							// Execute the appropriate callbacks
9583							jqXHR.always( map[ jqXHR.status ] );
9584						} else {
9585
9586							// Lazy-add the new callbacks in a way that preserves old ones
9587							for ( code in map ) {
9588								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9589							}
9590						}
9591					}
9592					return this;
9593				},
9594
9595				// Cancel the request
9596				abort: function( statusText ) {
9597					var finalText = statusText || strAbort;
9598					if ( transport ) {
9599						transport.abort( finalText );
9600					}
9601					done( 0, finalText );
9602					return this;
9603				}
9604			};
9605
9606		// Attach deferreds
9607		deferred.promise( jqXHR );
9608
9609		// Add protocol if not provided (prefilters might expect it)
9610		// Handle falsy url in the settings object (#10093: consistency with old signature)
9611		// We also use the url parameter if available
9612		s.url = ( ( url || s.url || location.href ) + "" )
9613			.replace( rprotocol, location.protocol + "//" );
9614
9615		// Alias method option to type as per ticket #12004
9616		s.type = options.method || options.type || s.method || s.type;
9617
9618		// Extract dataTypes list
9619		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9620
9621		// A cross-domain request is in order when the origin doesn't match the current origin.
9622		if ( s.crossDomain == null ) {
9623			urlAnchor = document.createElement( "a" );
9624
9625			// Support: IE <=8 - 11, Edge 12 - 15
9626			// IE throws exception on accessing the href property if url is malformed,
9627			// e.g. http://example.com:80x/
9628			try {
9629				urlAnchor.href = s.url;
9630
9631				// Support: IE <=8 - 11 only
9632				// Anchor's host property isn't correctly set when s.url is relative
9633				urlAnchor.href = urlAnchor.href;
9634				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9635					urlAnchor.protocol + "//" + urlAnchor.host;
9636			} catch ( e ) {
9637
9638				// If there is an error parsing the URL, assume it is crossDomain,
9639				// it can be rejected by the transport if it is invalid
9640				s.crossDomain = true;
9641			}
9642		}
9643
9644		// Convert data if not already a string
9645		if ( s.data && s.processData && typeof s.data !== "string" ) {
9646			s.data = jQuery.param( s.data, s.traditional );
9647		}
9648
9649		// Apply prefilters
9650		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9651
9652		// If request was aborted inside a prefilter, stop there
9653		if ( completed ) {
9654			return jqXHR;
9655		}
9656
9657		// We can fire global events as of now if asked to
9658		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9659		fireGlobals = jQuery.event && s.global;
9660
9661		// Watch for a new set of requests
9662		if ( fireGlobals && jQuery.active++ === 0 ) {
9663			jQuery.event.trigger( "ajaxStart" );
9664		}
9665
9666		// Uppercase the type
9667		s.type = s.type.toUpperCase();
9668
9669		// Determine if request has content
9670		s.hasContent = !rnoContent.test( s.type );
9671
9672		// Save the URL in case we're toying with the If-Modified-Since
9673		// and/or If-None-Match header later on
9674		// Remove hash to simplify url manipulation
9675		cacheURL = s.url.replace( rhash, "" );
9676
9677		// More options handling for requests with no content
9678		if ( !s.hasContent ) {
9679
9680			// Remember the hash so we can put it back
9681			uncached = s.url.slice( cacheURL.length );
9682
9683			// If data is available and should be processed, append data to url
9684			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
9685				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9686
9687				// #9682: remove data so that it's not used in an eventual retry
9688				delete s.data;
9689			}
9690
9691			// Add or update anti-cache param if needed
9692			if ( s.cache === false ) {
9693				cacheURL = cacheURL.replace( rantiCache, "$1" );
9694				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
9695					uncached;
9696			}
9697
9698			// Put hash and anti-cache on the URL that will be requested (gh-1732)
9699			s.url = cacheURL + uncached;
9700
9701		// Change '%20' to '+' if this is encoded form body content (gh-2658)
9702		} else if ( s.data && s.processData &&
9703			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9704			s.data = s.data.replace( r20, "+" );
9705		}
9706
9707		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9708		if ( s.ifModified ) {
9709			if ( jQuery.lastModified[ cacheURL ] ) {
9710				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9711			}
9712			if ( jQuery.etag[ cacheURL ] ) {
9713				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9714			}
9715		}
9716
9717		// Set the correct header, if data is being sent
9718		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9719			jqXHR.setRequestHeader( "Content-Type", s.contentType );
9720		}
9721
9722		// Set the Accepts header for the server, depending on the dataType
9723		jqXHR.setRequestHeader(
9724			"Accept",
9725			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9726				s.accepts[ s.dataTypes[ 0 ] ] +
9727					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9728				s.accepts[ "*" ]
9729		);
9730
9731		// Check for headers option
9732		for ( i in s.headers ) {
9733			jqXHR.setRequestHeader( i, s.headers[ i ] );
9734		}
9735
9736		// Allow custom headers/mimetypes and early abort
9737		if ( s.beforeSend &&
9738			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9739
9740			// Abort if not done already and return
9741			return jqXHR.abort();
9742		}
9743
9744		// Aborting is no longer a cancellation
9745		strAbort = "abort";
9746
9747		// Install callbacks on deferreds
9748		completeDeferred.add( s.complete );
9749		jqXHR.done( s.success );
9750		jqXHR.fail( s.error );
9751
9752		// Get transport
9753		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9754
9755		// If no transport, we auto-abort
9756		if ( !transport ) {
9757			done( -1, "No Transport" );
9758		} else {
9759			jqXHR.readyState = 1;
9760
9761			// Send global event
9762			if ( fireGlobals ) {
9763				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9764			}
9765
9766			// If request was aborted inside ajaxSend, stop there
9767			if ( completed ) {
9768				return jqXHR;
9769			}
9770
9771			// Timeout
9772			if ( s.async && s.timeout > 0 ) {
9773				timeoutTimer = window.setTimeout( function() {
9774					jqXHR.abort( "timeout" );
9775				}, s.timeout );
9776			}
9777
9778			try {
9779				completed = false;
9780				transport.send( requestHeaders, done );
9781			} catch ( e ) {
9782
9783				// Rethrow post-completion exceptions
9784				if ( completed ) {
9785					throw e;
9786				}
9787
9788				// Propagate others as results
9789				done( -1, e );
9790			}
9791		}
9792
9793		// Callback for when everything is done
9794		function done( status, nativeStatusText, responses, headers ) {
9795			var isSuccess, success, error, response, modified,
9796				statusText = nativeStatusText;
9797
9798			// Ignore repeat invocations
9799			if ( completed ) {
9800				return;
9801			}
9802
9803			completed = true;
9804
9805			// Clear timeout if it exists
9806			if ( timeoutTimer ) {
9807				window.clearTimeout( timeoutTimer );
9808			}
9809
9810			// Dereference transport for early garbage collection
9811			// (no matter how long the jqXHR object will be used)
9812			transport = undefined;
9813
9814			// Cache response headers
9815			responseHeadersString = headers || "";
9816
9817			// Set readyState
9818			jqXHR.readyState = status > 0 ? 4 : 0;
9819
9820			// Determine if successful
9821			isSuccess = status >= 200 && status < 300 || status === 304;
9822
9823			// Get response data
9824			if ( responses ) {
9825				response = ajaxHandleResponses( s, jqXHR, responses );
9826			}
9827
9828			// Use a noop converter for missing script but not if jsonp
9829			if ( !isSuccess &&
9830				jQuery.inArray( "script", s.dataTypes ) > -1 &&
9831				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
9832				s.converters[ "text script" ] = function() {};
9833			}
9834
9835			// Convert no matter what (that way responseXXX fields are always set)
9836			response = ajaxConvert( s, response, jqXHR, isSuccess );
9837
9838			// If successful, handle type chaining
9839			if ( isSuccess ) {
9840
9841				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9842				if ( s.ifModified ) {
9843					modified = jqXHR.getResponseHeader( "Last-Modified" );
9844					if ( modified ) {
9845						jQuery.lastModified[ cacheURL ] = modified;
9846					}
9847					modified = jqXHR.getResponseHeader( "etag" );
9848					if ( modified ) {
9849						jQuery.etag[ cacheURL ] = modified;
9850					}
9851				}
9852
9853				// if no content
9854				if ( status === 204 || s.type === "HEAD" ) {
9855					statusText = "nocontent";
9856
9857				// if not modified
9858				} else if ( status === 304 ) {
9859					statusText = "notmodified";
9860
9861				// If we have data, let's convert it
9862				} else {
9863					statusText = response.state;
9864					success = response.data;
9865					error = response.error;
9866					isSuccess = !error;
9867				}
9868			} else {
9869
9870				// Extract error from statusText and normalize for non-aborts
9871				error = statusText;
9872				if ( status || !statusText ) {
9873					statusText = "error";
9874					if ( status < 0 ) {
9875						status = 0;
9876					}
9877				}
9878			}
9879
9880			// Set data for the fake xhr object
9881			jqXHR.status = status;
9882			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9883
9884			// Success/Error
9885			if ( isSuccess ) {
9886				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9887			} else {
9888				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9889			}
9890
9891			// Status-dependent callbacks
9892			jqXHR.statusCode( statusCode );
9893			statusCode = undefined;
9894
9895			if ( fireGlobals ) {
9896				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9897					[ jqXHR, s, isSuccess ? success : error ] );
9898			}
9899
9900			// Complete
9901			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9902
9903			if ( fireGlobals ) {
9904				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9905
9906				// Handle the global AJAX counter
9907				if ( !( --jQuery.active ) ) {
9908					jQuery.event.trigger( "ajaxStop" );
9909				}
9910			}
9911		}
9912
9913		return jqXHR;
9914	},
9915
9916	getJSON: function( url, data, callback ) {
9917		return jQuery.get( url, data, callback, "json" );
9918	},
9919
9920	getScript: function( url, callback ) {
9921		return jQuery.get( url, undefined, callback, "script" );
9922	}
9923} );
9924
9925jQuery.each( [ "get", "post" ], function( _i, method ) {
9926	jQuery[ method ] = function( url, data, callback, type ) {
9927
9928		// Shift arguments if data argument was omitted
9929		if ( isFunction( data ) ) {
9930			type = type || callback;
9931			callback = data;
9932			data = undefined;
9933		}
9934
9935		// The url can be an options object (which then must have .url)
9936		return jQuery.ajax( jQuery.extend( {
9937			url: url,
9938			type: method,
9939			dataType: type,
9940			data: data,
9941			success: callback
9942		}, jQuery.isPlainObject( url ) && url ) );
9943	};
9944} );
9945
9946jQuery.ajaxPrefilter( function( s ) {
9947	var i;
9948	for ( i in s.headers ) {
9949		if ( i.toLowerCase() === "content-type" ) {
9950			s.contentType = s.headers[ i ] || "";
9951		}
9952	}
9953} );
9954
9955
9956jQuery._evalUrl = function( url, options, doc ) {
9957	return jQuery.ajax( {
9958		url: url,
9959
9960		// Make this explicit, since user can override this through ajaxSetup (#11264)
9961		type: "GET",
9962		dataType: "script",
9963		cache: true,
9964		async: false,
9965		global: false,
9966
9967		// Only evaluate the response if it is successful (gh-4126)
9968		// dataFilter is not invoked for failure responses, so using it instead
9969		// of the default converter is kludgy but it works.
9970		converters: {
9971			"text script": function() {}
9972		},
9973		dataFilter: function( response ) {
9974			jQuery.globalEval( response, options, doc );
9975		}
9976	} );
9977};
9978
9979
9980jQuery.fn.extend( {
9981	wrapAll: function( html ) {
9982		var wrap;
9983
9984		if ( this[ 0 ] ) {
9985			if ( isFunction( html ) ) {
9986				html = html.call( this[ 0 ] );
9987			}
9988
9989			// The elements to wrap the target around
9990			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9991
9992			if ( this[ 0 ].parentNode ) {
9993				wrap.insertBefore( this[ 0 ] );
9994			}
9995
9996			wrap.map( function() {
9997				var elem = this;
9998
9999				while ( elem.firstElementChild ) {
10000					elem = elem.firstElementChild;
10001				}
10002
10003				return elem;
10004			} ).append( this );
10005		}
10006
10007		return this;
10008	},
10009
10010	wrapInner: function( html ) {
10011		if ( isFunction( html ) ) {
10012			return this.each( function( i ) {
10013				jQuery( this ).wrapInner( html.call( this, i ) );
10014			} );
10015		}
10016
10017		return this.each( function() {
10018			var self = jQuery( this ),
10019				contents = self.contents();
10020
10021			if ( contents.length ) {
10022				contents.wrapAll( html );
10023
10024			} else {
10025				self.append( html );
10026			}
10027		} );
10028	},
10029
10030	wrap: function( html ) {
10031		var htmlIsFunction = isFunction( html );
10032
10033		return this.each( function( i ) {
10034			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
10035		} );
10036	},
10037
10038	unwrap: function( selector ) {
10039		this.parent( selector ).not( "body" ).each( function() {
10040			jQuery( this ).replaceWith( this.childNodes );
10041		} );
10042		return this;
10043	}
10044} );
10045
10046
10047jQuery.expr.pseudos.hidden = function( elem ) {
10048	return !jQuery.expr.pseudos.visible( elem );
10049};
10050jQuery.expr.pseudos.visible = function( elem ) {
10051	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
10052};
10053
10054
10055
10056
10057jQuery.ajaxSettings.xhr = function() {
10058	try {
10059		return new window.XMLHttpRequest();
10060	} catch ( e ) {}
10061};
10062
10063var xhrSuccessStatus = {
10064
10065		// File protocol always yields status code 0, assume 200
10066		0: 200,
10067
10068		// Support: IE <=9 only
10069		// #1450: sometimes IE returns 1223 when it should be 204
10070		1223: 204
10071	},
10072	xhrSupported = jQuery.ajaxSettings.xhr();
10073
10074support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10075support.ajax = xhrSupported = !!xhrSupported;
10076
10077jQuery.ajaxTransport( function( options ) {
10078	var callback, errorCallback;
10079
10080	// Cross domain only allowed if supported through XMLHttpRequest
10081	if ( support.cors || xhrSupported && !options.crossDomain ) {
10082		return {
10083			send: function( headers, complete ) {
10084				var i,
10085					xhr = options.xhr();
10086
10087				xhr.open(
10088					options.type,
10089					options.url,
10090					options.async,
10091					options.username,
10092					options.password
10093				);
10094
10095				// Apply custom fields if provided
10096				if ( options.xhrFields ) {
10097					for ( i in options.xhrFields ) {
10098						xhr[ i ] = options.xhrFields[ i ];
10099					}
10100				}
10101
10102				// Override mime type if needed
10103				if ( options.mimeType && xhr.overrideMimeType ) {
10104					xhr.overrideMimeType( options.mimeType );
10105				}
10106
10107				// X-Requested-With header
10108				// For cross-domain requests, seeing as conditions for a preflight are
10109				// akin to a jigsaw puzzle, we simply never set it to be sure.
10110				// (it can always be set on a per-request basis or even using ajaxSetup)
10111				// For same-domain requests, won't change header if already provided.
10112				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10113					headers[ "X-Requested-With" ] = "XMLHttpRequest";
10114				}
10115
10116				// Set headers
10117				for ( i in headers ) {
10118					xhr.setRequestHeader( i, headers[ i ] );
10119				}
10120
10121				// Callback
10122				callback = function( type ) {
10123					return function() {
10124						if ( callback ) {
10125							callback = errorCallback = xhr.onload =
10126								xhr.onerror = xhr.onabort = xhr.ontimeout =
10127									xhr.onreadystatechange = null;
10128
10129							if ( type === "abort" ) {
10130								xhr.abort();
10131							} else if ( type === "error" ) {
10132
10133								// Support: IE <=9 only
10134								// On a manual native abort, IE9 throws
10135								// errors on any property access that is not readyState
10136								if ( typeof xhr.status !== "number" ) {
10137									complete( 0, "error" );
10138								} else {
10139									complete(
10140
10141										// File: protocol always yields status 0; see #8605, #14207
10142										xhr.status,
10143										xhr.statusText
10144									);
10145								}
10146							} else {
10147								complete(
10148									xhrSuccessStatus[ xhr.status ] || xhr.status,
10149									xhr.statusText,
10150
10151									// Support: IE <=9 only
10152									// IE9 has no XHR2 but throws on binary (trac-11426)
10153									// For XHR2 non-text, let the caller handle it (gh-2498)
10154									( xhr.responseType || "text" ) !== "text"  ||
10155									typeof xhr.responseText !== "string" ?
10156										{ binary: xhr.response } :
10157										{ text: xhr.responseText },
10158									xhr.getAllResponseHeaders()
10159								);
10160							}
10161						}
10162					};
10163				};
10164
10165				// Listen to events
10166				xhr.onload = callback();
10167				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
10168
10169				// Support: IE 9 only
10170				// Use onreadystatechange to replace onabort
10171				// to handle uncaught aborts
10172				if ( xhr.onabort !== undefined ) {
10173					xhr.onabort = errorCallback;
10174				} else {
10175					xhr.onreadystatechange = function() {
10176
10177						// Check readyState before timeout as it changes
10178						if ( xhr.readyState === 4 ) {
10179
10180							// Allow onerror to be called first,
10181							// but that will not handle a native abort
10182							// Also, save errorCallback to a variable
10183							// as xhr.onerror cannot be accessed
10184							window.setTimeout( function() {
10185								if ( callback ) {
10186									errorCallback();
10187								}
10188							} );
10189						}
10190					};
10191				}
10192
10193				// Create the abort callback
10194				callback = callback( "abort" );
10195
10196				try {
10197
10198					// Do send the request (this may raise an exception)
10199					xhr.send( options.hasContent && options.data || null );
10200				} catch ( e ) {
10201
10202					// #14683: Only rethrow if this hasn't been notified as an error yet
10203					if ( callback ) {
10204						throw e;
10205					}
10206				}
10207			},
10208
10209			abort: function() {
10210				if ( callback ) {
10211					callback();
10212				}
10213			}
10214		};
10215	}
10216} );
10217
10218
10219
10220
10221// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10222jQuery.ajaxPrefilter( function( s ) {
10223	if ( s.crossDomain ) {
10224		s.contents.script = false;
10225	}
10226} );
10227
10228// Install script dataType
10229jQuery.ajaxSetup( {
10230	accepts: {
10231		script: "text/javascript, application/javascript, " +
10232			"application/ecmascript, application/x-ecmascript"
10233	},
10234	contents: {
10235		script: /\b(?:java|ecma)script\b/
10236	},
10237	converters: {
10238		"text script": function( text ) {
10239			jQuery.globalEval( text );
10240			return text;
10241		}
10242	}
10243} );
10244
10245// Handle cache's special case and crossDomain
10246jQuery.ajaxPrefilter( "script", function( s ) {
10247	if ( s.cache === undefined ) {
10248		s.cache = false;
10249	}
10250	if ( s.crossDomain ) {
10251		s.type = "GET";
10252	}
10253} );
10254
10255// Bind script tag hack transport
10256jQuery.ajaxTransport( "script", function( s ) {
10257
10258	// This transport only deals with cross domain or forced-by-attrs requests
10259	if ( s.crossDomain || s.scriptAttrs ) {
10260		var script, callback;
10261		return {
10262			send: function( _, complete ) {
10263				script = jQuery( "<script>" )
10264					.attr( s.scriptAttrs || {} )
10265					.prop( { charset: s.scriptCharset, src: s.url } )
10266					.on( "load error", callback = function( evt ) {
10267						script.remove();
10268						callback = null;
10269						if ( evt ) {
10270							complete( evt.type === "error" ? 404 : 200, evt.type );
10271						}
10272					} );
10273
10274				// Use native DOM manipulation to avoid our domManip AJAX trickery
10275				document.head.appendChild( script[ 0 ] );
10276			},
10277			abort: function() {
10278				if ( callback ) {
10279					callback();
10280				}
10281			}
10282		};
10283	}
10284} );
10285
10286
10287
10288
10289var oldCallbacks = [],
10290	rjsonp = /(=)\?(?=&|$)|\?\?/;
10291
10292// Default jsonp settings
10293jQuery.ajaxSetup( {
10294	jsonp: "callback",
10295	jsonpCallback: function() {
10296		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
10297		this[ callback ] = true;
10298		return callback;
10299	}
10300} );
10301
10302// Detect, normalize options and install callbacks for jsonp requests
10303jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10304
10305	var callbackName, overwritten, responseContainer,
10306		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10307			"url" :
10308			typeof s.data === "string" &&
10309				( s.contentType || "" )
10310					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10311				rjsonp.test( s.data ) && "data"
10312		);
10313
10314	// Handle iff the expected data type is "jsonp" or we have a parameter to set
10315	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10316
10317		// Get callback name, remembering preexisting value associated with it
10318		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
10319			s.jsonpCallback() :
10320			s.jsonpCallback;
10321
10322		// Insert callback into url or form data
10323		if ( jsonProp ) {
10324			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10325		} else if ( s.jsonp !== false ) {
10326			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10327		}
10328
10329		// Use data converter to retrieve json after script execution
10330		s.converters[ "script json" ] = function() {
10331			if ( !responseContainer ) {
10332				jQuery.error( callbackName + " was not called" );
10333			}
10334			return responseContainer[ 0 ];
10335		};
10336
10337		// Force json dataType
10338		s.dataTypes[ 0 ] = "json";
10339
10340		// Install callback
10341		overwritten = window[ callbackName ];
10342		window[ callbackName ] = function() {
10343			responseContainer = arguments;
10344		};
10345
10346		// Clean-up function (fires after converters)
10347		jqXHR.always( function() {
10348
10349			// If previous value didn't exist - remove it
10350			if ( overwritten === undefined ) {
10351				jQuery( window ).removeProp( callbackName );
10352
10353			// Otherwise restore preexisting value
10354			} else {
10355				window[ callbackName ] = overwritten;
10356			}
10357
10358			// Save back as free
10359			if ( s[ callbackName ] ) {
10360
10361				// Make sure that re-using the options doesn't screw things around
10362				s.jsonpCallback = originalSettings.jsonpCallback;
10363
10364				// Save the callback name for future use
10365				oldCallbacks.push( callbackName );
10366			}
10367
10368			// Call if it was a function and we have a response
10369			if ( responseContainer && isFunction( overwritten ) ) {
10370				overwritten( responseContainer[ 0 ] );
10371			}
10372
10373			responseContainer = overwritten = undefined;
10374		} );
10375
10376		// Delegate to script
10377		return "script";
10378	}
10379} );
10380
10381
10382
10383
10384// Support: Safari 8 only
10385// In Safari 8 documents created via document.implementation.createHTMLDocument
10386// collapse sibling forms: the second one becomes a child of the first one.
10387// Because of that, this security measure has to be disabled in Safari 8.
10388// https://bugs.webkit.org/show_bug.cgi?id=137337
10389support.createHTMLDocument = ( function() {
10390	var body = document.implementation.createHTMLDocument( "" ).body;
10391	body.innerHTML = "<form></form><form></form>";
10392	return body.childNodes.length === 2;
10393} )();
10394
10395
10396// Argument "data" should be string of html
10397// context (optional): If specified, the fragment will be created in this context,
10398// defaults to document
10399// keepScripts (optional): If true, will include scripts passed in the html string
10400jQuery.parseHTML = function( data, context, keepScripts ) {
10401	if ( typeof data !== "string" ) {
10402		return [];
10403	}
10404	if ( typeof context === "boolean" ) {
10405		keepScripts = context;
10406		context = false;
10407	}
10408
10409	var base, parsed, scripts;
10410
10411	if ( !context ) {
10412
10413		// Stop scripts or inline event handlers from being executed immediately
10414		// by using document.implementation
10415		if ( support.createHTMLDocument ) {
10416			context = document.implementation.createHTMLDocument( "" );
10417
10418			// Set the base href for the created document
10419			// so any parsed elements with URLs
10420			// are based on the document's URL (gh-2965)
10421			base = context.createElement( "base" );
10422			base.href = document.location.href;
10423			context.head.appendChild( base );
10424		} else {
10425			context = document;
10426		}
10427	}
10428
10429	parsed = rsingleTag.exec( data );
10430	scripts = !keepScripts && [];
10431
10432	// Single tag
10433	if ( parsed ) {
10434		return [ context.createElement( parsed[ 1 ] ) ];
10435	}
10436
10437	parsed = buildFragment( [ data ], context, scripts );
10438
10439	if ( scripts && scripts.length ) {
10440		jQuery( scripts ).remove();
10441	}
10442
10443	return jQuery.merge( [], parsed.childNodes );
10444};
10445
10446
10447/**
10448 * Load a url into a page
10449 */
10450jQuery.fn.load = function( url, params, callback ) {
10451	var selector, type, response,
10452		self = this,
10453		off = url.indexOf( " " );
10454
10455	if ( off > -1 ) {
10456		selector = stripAndCollapse( url.slice( off ) );
10457		url = url.slice( 0, off );
10458	}
10459
10460	// If it's a function
10461	if ( isFunction( params ) ) {
10462
10463		// We assume that it's the callback
10464		callback = params;
10465		params = undefined;
10466
10467	// Otherwise, build a param string
10468	} else if ( params && typeof params === "object" ) {
10469		type = "POST";
10470	}
10471
10472	// If we have elements to modify, make the request
10473	if ( self.length > 0 ) {
10474		jQuery.ajax( {
10475			url: url,
10476
10477			// If "type" variable is undefined, then "GET" method will be used.
10478			// Make value of this field explicit since
10479			// user can override it through ajaxSetup method
10480			type: type || "GET",
10481			dataType: "html",
10482			data: params
10483		} ).done( function( responseText ) {
10484
10485			// Save response for use in complete callback
10486			response = arguments;
10487
10488			self.html( selector ?
10489
10490				// If a selector was specified, locate the right elements in a dummy div
10491				// Exclude scripts to avoid IE 'Permission Denied' errors
10492				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10493
10494				// Otherwise use the full result
10495				responseText );
10496
10497		// If the request succeeds, this function gets "data", "status", "jqXHR"
10498		// but they are ignored because response was set above.
10499		// If it fails, this function gets "jqXHR", "status", "error"
10500		} ).always( callback && function( jqXHR, status ) {
10501			self.each( function() {
10502				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10503			} );
10504		} );
10505	}
10506
10507	return this;
10508};
10509
10510
10511
10512
10513jQuery.expr.pseudos.animated = function( elem ) {
10514	return jQuery.grep( jQuery.timers, function( fn ) {
10515		return elem === fn.elem;
10516	} ).length;
10517};
10518
10519
10520
10521
10522jQuery.offset = {
10523	setOffset: function( elem, options, i ) {
10524		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10525			position = jQuery.css( elem, "position" ),
10526			curElem = jQuery( elem ),
10527			props = {};
10528
10529		// Set position first, in-case top/left are set even on static elem
10530		if ( position === "static" ) {
10531			elem.style.position = "relative";
10532		}
10533
10534		curOffset = curElem.offset();
10535		curCSSTop = jQuery.css( elem, "top" );
10536		curCSSLeft = jQuery.css( elem, "left" );
10537		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10538			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
10539
10540		// Need to be able to calculate position if either
10541		// top or left is auto and position is either absolute or fixed
10542		if ( calculatePosition ) {
10543			curPosition = curElem.position();
10544			curTop = curPosition.top;
10545			curLeft = curPosition.left;
10546
10547		} else {
10548			curTop = parseFloat( curCSSTop ) || 0;
10549			curLeft = parseFloat( curCSSLeft ) || 0;
10550		}
10551
10552		if ( isFunction( options ) ) {
10553
10554			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10555			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10556		}
10557
10558		if ( options.top != null ) {
10559			props.top = ( options.top - curOffset.top ) + curTop;
10560		}
10561		if ( options.left != null ) {
10562			props.left = ( options.left - curOffset.left ) + curLeft;
10563		}
10564
10565		if ( "using" in options ) {
10566			options.using.call( elem, props );
10567
10568		} else {
10569			curElem.css( props );
10570		}
10571	}
10572};
10573
10574jQuery.fn.extend( {
10575
10576	// offset() relates an element's border box to the document origin
10577	offset: function( options ) {
10578
10579		// Preserve chaining for setter
10580		if ( arguments.length ) {
10581			return options === undefined ?
10582				this :
10583				this.each( function( i ) {
10584					jQuery.offset.setOffset( this, options, i );
10585				} );
10586		}
10587
10588		var rect, win,
10589			elem = this[ 0 ];
10590
10591		if ( !elem ) {
10592			return;
10593		}
10594
10595		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10596		// Support: IE <=11 only
10597		// Running getBoundingClientRect on a
10598		// disconnected node in IE throws an error
10599		if ( !elem.getClientRects().length ) {
10600			return { top: 0, left: 0 };
10601		}
10602
10603		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
10604		rect = elem.getBoundingClientRect();
10605		win = elem.ownerDocument.defaultView;
10606		return {
10607			top: rect.top + win.pageYOffset,
10608			left: rect.left + win.pageXOffset
10609		};
10610	},
10611
10612	// position() relates an element's margin box to its offset parent's padding box
10613	// This corresponds to the behavior of CSS absolute positioning
10614	position: function() {
10615		if ( !this[ 0 ] ) {
10616			return;
10617		}
10618
10619		var offsetParent, offset, doc,
10620			elem = this[ 0 ],
10621			parentOffset = { top: 0, left: 0 };
10622
10623		// position:fixed elements are offset from the viewport, which itself always has zero offset
10624		if ( jQuery.css( elem, "position" ) === "fixed" ) {
10625
10626			// Assume position:fixed implies availability of getBoundingClientRect
10627			offset = elem.getBoundingClientRect();
10628
10629		} else {
10630			offset = this.offset();
10631
10632			// Account for the *real* offset parent, which can be the document or its root element
10633			// when a statically positioned element is identified
10634			doc = elem.ownerDocument;
10635			offsetParent = elem.offsetParent || doc.documentElement;
10636			while ( offsetParent &&
10637				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
10638				jQuery.css( offsetParent, "position" ) === "static" ) {
10639
10640				offsetParent = offsetParent.parentNode;
10641			}
10642			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
10643
10644				// Incorporate borders into its offset, since they are outside its content origin
10645				parentOffset = jQuery( offsetParent ).offset();
10646				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
10647				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
10648			}
10649		}
10650
10651		// Subtract parent offsets and element margins
10652		return {
10653			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10654			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10655		};
10656	},
10657
10658	// This method will return documentElement in the following cases:
10659	// 1) For the element inside the iframe without offsetParent, this method will return
10660	//    documentElement of the parent window
10661	// 2) For the hidden or detached element
10662	// 3) For body or html element, i.e. in case of the html node - it will return itself
10663	//
10664	// but those exceptions were never presented as a real life use-cases
10665	// and might be considered as more preferable results.
10666	//
10667	// This logic, however, is not guaranteed and can change at any point in the future
10668	offsetParent: function() {
10669		return this.map( function() {
10670			var offsetParent = this.offsetParent;
10671
10672			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10673				offsetParent = offsetParent.offsetParent;
10674			}
10675
10676			return offsetParent || documentElement;
10677		} );
10678	}
10679} );
10680
10681// Create scrollLeft and scrollTop methods
10682jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10683	var top = "pageYOffset" === prop;
10684
10685	jQuery.fn[ method ] = function( val ) {
10686		return access( this, function( elem, method, val ) {
10687
10688			// Coalesce documents and windows
10689			var win;
10690			if ( isWindow( elem ) ) {
10691				win = elem;
10692			} else if ( elem.nodeType === 9 ) {
10693				win = elem.defaultView;
10694			}
10695
10696			if ( val === undefined ) {
10697				return win ? win[ prop ] : elem[ method ];
10698			}
10699
10700			if ( win ) {
10701				win.scrollTo(
10702					!top ? val : win.pageXOffset,
10703					top ? val : win.pageYOffset
10704				);
10705
10706			} else {
10707				elem[ method ] = val;
10708			}
10709		}, method, val, arguments.length );
10710	};
10711} );
10712
10713// Support: Safari <=7 - 9.1, Chrome <=37 - 49
10714// Add the top/left cssHooks using jQuery.fn.position
10715// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10716// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10717// getComputedStyle returns percent when specified for top/left/bottom/right;
10718// rather than make the css module depend on the offset module, just check for it here
10719jQuery.each( [ "top", "left" ], function( _i, prop ) {
10720	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10721		function( elem, computed ) {
10722			if ( computed ) {
10723				computed = curCSS( elem, prop );
10724
10725				// If curCSS returns percentage, fallback to offset
10726				return rnumnonpx.test( computed ) ?
10727					jQuery( elem ).position()[ prop ] + "px" :
10728					computed;
10729			}
10730		}
10731	);
10732} );
10733
10734
10735// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10736jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10737	jQuery.each( {
10738		padding: "inner" + name,
10739		content: type,
10740		"": "outer" + name
10741	}, function( defaultExtra, funcName ) {
10742
10743		// Margin is only for outerHeight, outerWidth
10744		jQuery.fn[ funcName ] = function( margin, value ) {
10745			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10746				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10747
10748			return access( this, function( elem, type, value ) {
10749				var doc;
10750
10751				if ( isWindow( elem ) ) {
10752
10753					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10754					return funcName.indexOf( "outer" ) === 0 ?
10755						elem[ "inner" + name ] :
10756						elem.document.documentElement[ "client" + name ];
10757				}
10758
10759				// Get document width or height
10760				if ( elem.nodeType === 9 ) {
10761					doc = elem.documentElement;
10762
10763					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10764					// whichever is greatest
10765					return Math.max(
10766						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10767						elem.body[ "offset" + name ], doc[ "offset" + name ],
10768						doc[ "client" + name ]
10769					);
10770				}
10771
10772				return value === undefined ?
10773
10774					// Get width or height on the element, requesting but not forcing parseFloat
10775					jQuery.css( elem, type, extra ) :
10776
10777					// Set width or height on the element
10778					jQuery.style( elem, type, value, extra );
10779			}, type, chainable ? margin : undefined, chainable );
10780		};
10781	} );
10782} );
10783
10784
10785jQuery.each( [
10786	"ajaxStart",
10787	"ajaxStop",
10788	"ajaxComplete",
10789	"ajaxError",
10790	"ajaxSuccess",
10791	"ajaxSend"
10792], function( _i, type ) {
10793	jQuery.fn[ type ] = function( fn ) {
10794		return this.on( type, fn );
10795	};
10796} );
10797
10798
10799
10800
10801jQuery.fn.extend( {
10802
10803	bind: function( types, data, fn ) {
10804		return this.on( types, null, data, fn );
10805	},
10806	unbind: function( types, fn ) {
10807		return this.off( types, null, fn );
10808	},
10809
10810	delegate: function( selector, types, data, fn ) {
10811		return this.on( types, selector, data, fn );
10812	},
10813	undelegate: function( selector, types, fn ) {
10814
10815		// ( namespace ) or ( selector, types [, fn] )
10816		return arguments.length === 1 ?
10817			this.off( selector, "**" ) :
10818			this.off( types, selector || "**", fn );
10819	},
10820
10821	hover: function( fnOver, fnOut ) {
10822		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
10823	}
10824} );
10825
10826jQuery.each(
10827	( "blur focus focusin focusout resize scroll click dblclick " +
10828	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10829	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
10830	function( _i, name ) {
10831
10832		// Handle event binding
10833		jQuery.fn[ name ] = function( data, fn ) {
10834			return arguments.length > 0 ?
10835				this.on( name, null, data, fn ) :
10836				this.trigger( name );
10837		};
10838	}
10839);
10840
10841
10842
10843
10844// Support: Android <=4.0 only
10845// Make sure we trim BOM and NBSP
10846var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
10847
10848// Bind a function to a context, optionally partially applying any
10849// arguments.
10850// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10851// However, it is not slated for removal any time soon
10852jQuery.proxy = function( fn, context ) {
10853	var tmp, args, proxy;
10854
10855	if ( typeof context === "string" ) {
10856		tmp = fn[ context ];
10857		context = fn;
10858		fn = tmp;
10859	}
10860
10861	// Quick check to determine if target is callable, in the spec
10862	// this throws a TypeError, but we will just return undefined.
10863	if ( !isFunction( fn ) ) {
10864		return undefined;
10865	}
10866
10867	// Simulated bind
10868	args = slice.call( arguments, 2 );
10869	proxy = function() {
10870		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
10871	};
10872
10873	// Set the guid of unique handler to the same of original handler, so it can be removed
10874	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10875
10876	return proxy;
10877};
10878
10879jQuery.holdReady = function( hold ) {
10880	if ( hold ) {
10881		jQuery.readyWait++;
10882	} else {
10883		jQuery.ready( true );
10884	}
10885};
10886jQuery.isArray = Array.isArray;
10887jQuery.parseJSON = JSON.parse;
10888jQuery.nodeName = nodeName;
10889jQuery.isFunction = isFunction;
10890jQuery.isWindow = isWindow;
10891jQuery.camelCase = camelCase;
10892jQuery.type = toType;
10893
10894jQuery.now = Date.now;
10895
10896jQuery.isNumeric = function( obj ) {
10897
10898	// As of jQuery 3.0, isNumeric is limited to
10899	// strings and numbers (primitives or objects)
10900	// that can be coerced to finite numbers (gh-2662)
10901	var type = jQuery.type( obj );
10902	return ( type === "number" || type === "string" ) &&
10903
10904		// parseFloat NaNs numeric-cast false positives ("")
10905		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10906		// subtraction forces infinities to NaN
10907		!isNaN( obj - parseFloat( obj ) );
10908};
10909
10910jQuery.trim = function( text ) {
10911	return text == null ?
10912		"" :
10913		( text + "" ).replace( rtrim, "" );
10914};
10915
10916
10917
10918// Register as a named AMD module, since jQuery can be concatenated with other
10919// files that may use define, but not via a proper concatenation script that
10920// understands anonymous AMD modules. A named AMD is safest and most robust
10921// way to register. Lowercase jquery is used because AMD module names are
10922// derived from file names, and jQuery is normally delivered in a lowercase
10923// file name. Do this after creating the global so that if an AMD module wants
10924// to call noConflict to hide this version of jQuery, it will work.
10925
10926// Note that for maximum portability, libraries that are not jQuery should
10927// declare themselves as anonymous modules, and avoid setting a global if an
10928// AMD loader is present. jQuery is a special case. For more information, see
10929// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10930
10931if ( t
10931rue ) {
10932	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {
10933		return jQuery;
10934	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
10935				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
10936}
10937
10938
10939
10940
10941var
10942
10943	// Map over jQuery in case of overwrite
10944	_jQuery = window.jQuery,
10945
10946	// Map over the $ in case of overwrite
10947	_$ = window.$;
10948
10949jQuery.noConflict = function( deep ) {
10950	if ( window.$ === jQuery ) {
10951		window.$ = _$;
10952	}
10953
10954	if ( deep && window.jQuery === jQuery ) {
10955		window.jQuery = _jQuery;
10956	}
10957
10958	return jQuery;
10959};
10960
10961// Expose jQuery and $ identifiers, even in AMD
10962// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10963// and CommonJS for browser emulators (#13566)
10964if ( typeof noGlobal === "undefined" ) {
10965	window.jQuery = window.$ = jQuery;
10966}
10967
10968
10969
10970
10971return jQuery;
10972} );
10973
10974
10975/***/ }),
10976/* 1 */
10977/***/ (function(module, exports, __webpack_require__) {
10978
10979var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! DataTables 1.11.3
10980 * ©2008-2021 SpryMedia Ltd - datatables.net/license
10981 */
10982
10983/**
10984 * @summary     DataTables
10985 * @description Paginate, search and order HTML tables
10986 * @version     1.11.3
10987 * @file        jquery.dataTables.js
10988 * @author      SpryMedia Ltd
10989 * @contact     www.datatables.net
10990 * @copyright   Copyright 2008-2021 SpryMedia Ltd.
10991 *
10992 * This source file is free software, available under the following license:
10993 *   MIT license - http://datatables.net/license
10994 *
10995 * This source file is distributed in the hope that it will be useful, but
10996 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10997 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
10998 *
10999 * For details please refer to: http://www.datatables.net
11000 */
11001
11002/*jslint evil: true, undef: true, browser: true */
11003/*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,_fnInvalidate,_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,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
11004
11005(function( factory ) {
11006	"use strict";
11007
11008	if ( true ) {
11009		// AMD
11010		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {
11011			return factory( $, window, document );
11012		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
11013				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
11014	}
11015	else {}
11016}
11017(function( $, window, document, undefined ) {
11018	"use strict";
11019
11020	/**
11021	 * DataTables is a plug-in for the jQuery Javascript library. It is a highly
11022	 * flexible tool, based upon the foundations of progressive enhancement,
11023	 * which will add advanced interaction controls to any HTML table. For a
11024	 * full list of features please refer to
11025	 * [DataTables.net](href="http://datatables.net).
11026	 *
11027	 * Note that the `DataTable` object is not a global variable but is aliased
11028	 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
11029	 * be  accessed.
11030	 *
11031	 *  @class
11032	 *  @param {object} [init={}] Configuration object for DataTables. Options
11033	 *    are defined by {@link DataTable.defaults}
11034	 *  @requires jQuery 1.7+
11035	 *
11036	 *  @example
11037	 *    // Basic initialisation
11038	 *    $(document).ready( function {
11039	 *      $('#example').dataTable();
11040	 *    } );
11041	 *
11042	 *  @example
11043	 *    // Initialisation with configuration options - in this case, disable
11044	 *    // pagination and sorting.
11045	 *    $(document).ready( function {
11046	 *      $('#example').dataTable( {
11047	 *        "paginate": false,
11048	 *        "sort": false
11049	 *      } );
11050	 *    } );
11051	 */
11052	var DataTable = function ( selector, options )
11053	{
11054		// When creating with `new`, create a new DataTable, returning the API instance
11055		if (this instanceof DataTable) {
11056			return $(selector).DataTable(options);
11057		}
11058		else {
11059			// Argument switching
11060			options = selector;
11061		}
vendor: 25,075 bytes, lines 11062-11817
11062
11063		/**
11064		 * Perform a jQuery selector action on the table's TR elements (from the tbody) and
11065		 * return the resulting jQuery object.
11066		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
11067		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
11068		 *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
11069		 *    criterion ("applied") or all TR elements (i.e. no filter).
11070		 *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
11071		 *    Can be either 'current', whereby the current sorting of the table is used, or
11072		 *    'original' whereby the original order the data was read into the table is used.
11073		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
11074		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
11075		 *    'current' and filter is 'applied', regardless of what they might be given as.
11076		 *  @returns {object} jQuery object, filtered by the given selector.
11077		 *  @dtopt API
11078		 *  @deprecated Since v1.10
11079		 *
11080		 *  @example
11081		 *    $(document).ready(function() {
11082		 *      var oTable = $('#example').dataTable();
11083		 *
11084		 *      // Highlight every second row
11085		 *      oTable.$('tr:odd').css('backgroundColor', 'blue');
11086		 *    } );
11087		 *
11088		 *  @example
11089		 *    $(document).ready(function() {
11090		 *      var oTable = $('#example').dataTable();
11091		 *
11092		 *      // Filter to rows with 'Webkit' in them, add a background colour and then
11093		 *      // remove the filter, thus highlighting the 'Webkit' rows only.
11094		 *      oTable.fnFilter('Webkit');
11095		 *      oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
11096		 *      oTable.fnFilter('');
11097		 *    } );
11098		 */
11099		this.$ = function ( sSelector, oOpts )
11100		{
11101			return this.api(true).$( sSelector, oOpts );
11102		};
11103		
11104		
11105		/**
11106		 * Almost identical to $ in operation, but in this case returns the data for the matched
11107		 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
11108		 * rather than any descendants, so the data can be obtained for the row/cell. If matching
11109		 * rows are found, the data returned is the original data array/object that was used to
11110		 * create the row (or a generated array if from a DOM source).
11111		 *
11112		 * This method is often useful in-combination with $ where both functions are given the
11113		 * same parameters and the array indexes will match identically.
11114		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
11115		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
11116		 *  @param {string} [oOpts.filter=none] Select elements that meet the current filter
11117		 *    criterion ("applied") or all elements (i.e. no filter).
11118		 *  @param {string} [oOpts.order=current] Order of the data in the processed array.
11119		 *    Can be either 'current', whereby the current sorting of the table is used, or
11120		 *    'original' whereby the original order the data was read into the table is used.
11121		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
11122		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
11123		 *    'current' and filter is 'applied', regardless of what they might be given as.
11124		 *  @returns {array} Data for the matched elements. If any elements, as a result of the
11125		 *    selector, were not TR, TD or TH elements in the DataTable, they will have a null
11126		 *    entry in the array.
11127		 *  @dtopt API
11128		 *  @deprecated Since v1.10
11129		 *
11130		 *  @example
11131		 *    $(document).ready(function() {
11132		 *      var oTable = $('#example').dataTable();
11133		 *
11134		 *      // Get the data from the first row in the table
11135		 *      var data = oTable._('tr:first');
11136		 *
11137		 *      // Do something useful with the data
11138		 *      alert( "First cell is: "+data[0] );
11139		 *    } );
11140		 *
11141		 *  @example
11142		 *    $(document).ready(function() {
11143		 *      var oTable = $('#example').dataTable();
11144		 *
11145		 *      // Filter to 'Webkit' and get all data for
11146		 *      oTable.fnFilter('Webkit');
11147		 *      var data = oTable._('tr', {"search": "applied"});
11148		 *
11149		 *      // Do something with the data
11150		 *      alert( data.length+" rows matched the search" );
11151		 *    } );
11152		 */
11153		this._ = function ( sSelector, oOpts )
11154		{
11155			return this.api(true).rows( sSelector, oOpts ).data();
11156		};
11157		
11158		
11159		/**
11160		 * Create a DataTables Api instance, with the currently selected tables for
11161		 * the Api's context.
11162		 * @param {boolean} [traditional=false] Set the API instance's context to be
11163		 *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was
11164		 *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),
11165		 *   or if all tables captured in the jQuery object should be used.
11166		 * @return {DataTables.Api}
11167		 */
11168		this.api = function ( traditional )
11169		{
11170			return traditional ?
11171				new _Api(
11172					_fnSettingsFromNode( this[ _ext.iApiIndex ] )
11173				) :
11174				new _Api( this );
11175		};
11176		
11177		
11178		/**
11179		 * Add a single new row or multiple rows of data to the table. Please note
11180		 * that this is suitable for client-side processing only - if you are using
11181		 * server-side processing (i.e. "bServerSide": true), then to add data, you
11182		 * must add it to the data source, i.e. the server-side, through an Ajax call.
11183		 *  @param {array|object} data The data to be added to the table. This can be:
11184		 *    <ul>
11185		 *      <li>1D array of data - add a single row with the data provided</li>
11186		 *      <li>2D array of arrays - add multiple rows in a single call</li>
11187		 *      <li>object - data object when using <i>mData</i></li>
11188		 *      <li>array of objects - multiple data objects when using <i>mData</i></li>
11189		 *    </ul>
11190		 *  @param {bool} [redraw=true] redraw the table or not
11191		 *  @returns {array} An array of integers, representing the list of indexes in
11192		 *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
11193		 *    the table.
11194		 *  @dtopt API
11195		 *  @deprecated Since v1.10
11196		 *
11197		 *  @example
11198		 *    // Global var for counter
11199		 *    var giCount = 2;
11200		 *
11201		 *    $(document).ready(function() {
11202		 *      $('#example').dataTable();
11203		 *    } );
11204		 *
11205		 *    function fnClickAddRow() {
11206		 *      $('#example').dataTable().fnAddData( [
11207		 *        giCount+".1",
11208		 *        giCount+".2",
11209		 *        giCount+".3",
11210		 *        giCount+".4" ]
11211		 *      );
11212		 *
11213		 *      giCount++;
11214		 *    }
11215		 */
11216		this.fnAddData = function( data, redraw )
11217		{
11218			var api = this.api( true );
11219		
11220			/* Check if we want to add multiple rows or not */
11221			var rows = Array.isArray(data) && ( Array.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
11222				api.rows.add( data ) :
11223				api.row.add( data );
11224		
11225			if ( redraw === undefined || redraw ) {
11226				api.draw();
11227			}
11228		
11229			return rows.flatten().toArray();
11230		};
11231		
11232		
11233		/**
11234		 * This function will make DataTables recalculate the column sizes, based on the data
11235		 * contained in the table and the sizes applied to the columns (in the DOM, CSS or
11236		 * through the sWidth parameter). This can be useful when the width of the table's
11237		 * parent element changes (for example a window resize).
11238		 *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
11239		 *  @dtopt API
11240		 *  @deprecated Since v1.10
11241		 *
11242		 *  @example
11243		 *    $(document).ready(function() {
11244		 *      var oTable = $('#example').dataTable( {
11245		 *        "sScrollY": "200px",
11246		 *        "bPaginate": false
11247		 *      } );
11248		 *
11249		 *      $(window).on('resize', function () {
11250		 *        oTable.fnAdjustColumnSizing();
11251		 *      } );
11252		 *    } );
11253		 */
11254		this.fnAdjustColumnSizing = function ( bRedraw )
11255		{
11256			var api = this.api( true ).columns.adjust();
11257			var settings = api.settings()[0];
11258			var scroll = settings.oScroll;
11259		
11260			if ( bRedraw === undefined || bRedraw ) {
11261				api.draw( false );
11262			}
11263			else if ( scroll.sX !== "" || scroll.sY !== "" ) {
11264				/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
11265				_fnScrollDraw( settings );
11266			}
11267		};
11268		
11269		
11270		/**
11271		 * Quickly and simply clear a table
11272		 *  @param {bool} [bRedraw=true] redraw the table or not
11273		 *  @dtopt API
11274		 *  @deprecated Since v1.10
11275		 *
11276		 *  @example
11277		 *    $(document).ready(function() {
11278		 *      var oTable = $('#example').dataTable();
11279		 *
11280		 *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
11281		 *      oTable.fnClearTable();
11282		 *    } );
11283		 */
11284		this.fnClearTable = function( bRedraw )
11285		{
11286			var api = this.api( true ).clear();
11287		
11288			if ( bRedraw === undefined || bRedraw ) {
11289				api.draw();
11290			}
11291		};
11292		
11293		
11294		/**
11295		 * The exact opposite of 'opening' a row, this function will close any rows which
11296		 * are currently 'open'.
11297		 *  @param {node} nTr the table row to 'close'
11298		 *  @returns {int} 0 on success, or 1 if failed (can't find the row)
11299		 *  @dtopt API
11300		 *  @deprecated Since v1.10
11301		 *
11302		 *  @example
11303		 *    $(document).ready(function() {
11304		 *      var oTable;
11305		 *
11306		 *      // 'open' an information row when a row is clicked on
11307		 *      $('#example tbody tr').click( function () {
11308		 *        if ( oTable.fnIsOpen(this) ) {
11309		 *          oTable.fnClose( this );
11310		 *        } else {
11311		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
11312		 *        }
11313		 *      } );
11314		 *
11315		 *      oTable = $('#example').dataTable();
11316		 *    } );
11317		 */
11318		this.fnClose = function( nTr )
11319		{
11320			this.api( true ).row( nTr ).child.hide();
11321		};
11322		
11323		
11324		/**
11325		 * Remove a row for the table
11326		 *  @param {mixed} target The index of the row from aoData to be deleted, or
11327		 *    the TR element you want to delete
11328		 *  @param {function|null} [callBack] Callback function
11329		 *  @param {bool} [redraw=true] Redraw the table or not
11330		 *  @returns {array} The row that was deleted
11331		 *  @dtopt API
11332		 *  @deprecated Since v1.10
11333		 *
11334		 *  @example
11335		 *    $(document).ready(function() {
11336		 *      var oTable = $('#example').dataTable();
11337		 *
11338		 *      // Immediately remove the first row
11339		 *      oTable.fnDeleteRow( 0 );
11340		 *    } );
11341		 */
11342		this.fnDeleteRow = function( target, callback, redraw )
11343		{
11344			var api = this.api( true );
11345			var rows = api.rows( target );
11346			var settings = rows.settings()[0];
11347			var data = settings.aoData[ rows[0][0] ];
11348		
11349			rows.remove();
11350		
11351			if ( callback ) {
11352				callback.call( this, settings, data );
11353			}
11354		
11355			if ( redraw === undefined || redraw ) {
11356				api.draw();
11357			}
11358		
11359			return data;
11360		};
11361		
11362		
11363		/**
11364		 * Restore the table to it's original state in the DOM by removing all of DataTables
11365		 * enhancements, alterations to the DOM structure of the table and event listeners.
11366		 *  @param {boolean} [remove=false] Completely remove the table from the DOM
11367		 *  @dtopt API
11368		 *  @deprecated Since v1.10
11369		 *
11370		 *  @example
11371		 *    $(document).ready(function() {
11372		 *      // This example is fairly pointless in reality, but shows how fnDestroy can be used
11373		 *      var oTable = $('#example').dataTable();
11374		 *      oTable.fnDestroy();
11375		 *    } );
11376		 */
11377		this.fnDestroy = function ( remove )
11378		{
11379			this.api( true ).destroy( remove );
11380		};
11381		
11382		
11383		/**
11384		 * Redraw the table
11385		 *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
11386		 *  @dtopt API
11387		 *  @deprecated Since v1.10
11388		 *
11389		 *  @example
11390		 *    $(document).ready(function() {
11391		 *      var oTable = $('#example').dataTable();
11392		 *
11393		 *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
11394		 *      oTable.fnDraw();
11395		 *    } );
11396		 */
11397		this.fnDraw = function( complete )
11398		{
11399			// Note that this isn't an exact match to the old call to _fnDraw - it takes
11400			// into account the new data, but can hold position.
11401			this.api( true ).draw( complete );
11402		};
11403		
11404		
11405		/**
11406		 * Filter the input based on data
11407		 *  @param {string} sInput String to filter the table on
11408		 *  @param {int|null} [iColumn] Column to limit filtering to
11409		 *  @param {bool} [bRegex=false] Treat as regular expression or not
11410		 *  @param {bool} [bSmart=true] Perform smart filtering or not
11411		 *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
11412		 *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
11413		 *  @dtopt API
11414		 *  @deprecated Since v1.10
11415		 *
11416		 *  @example
11417		 *    $(document).ready(function() {
11418		 *      var oTable = $('#example').dataTable();
11419		 *
11420		 *      // Sometime later - filter...
11421		 *      oTable.fnFilter( 'test string' );
11422		 *    } );
11423		 */
11424		this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
11425		{
11426			var api = this.api( true );
11427		
11428			if ( iColumn === null || iColumn === undefined ) {
11429				api.search( sInput, bRegex, bSmart, bCaseInsensitive );
11430			}
11431			else {
11432				api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
11433			}
11434		
11435			api.draw();
11436		};
11437		
11438		
11439		/**
11440		 * Get the data for the whole table, an individual row or an individual cell based on the
11441		 * provided parameters.
11442		 *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
11443		 *    a TR node then the data source for the whole row will be returned. If given as a
11444		 *    TD/TH cell node then iCol will be automatically calculated and the data for the
11445		 *    cell returned. If given as an integer, then this is treated as the aoData internal
11446		 *    data index for the row (see fnGetPosition) and the data for that row used.
11447		 *  @param {int} [col] Optional column index that you want the data of.
11448		 *  @returns {array|object|string} If mRow is undefined, then the data for all rows is
11449		 *    returned. If mRow is defined, just data for that row, and is iCol is
11450		 *    defined, only data for the designated cell is returned.
11451		 *  @dtopt API
11452		 *  @deprecated Since v1.10
11453		 *
11454		 *  @example
11455		 *    // Row data
11456		 *    $(document).ready(function() {
11457		 *      oTable = $('#example').dataTable();
11458		 *
11459		 *      oTable.$('tr').click( function () {
11460		 *        var data = oTable.fnGetData( this );
11461		 *        // ... do something with the array / object of data for the row
11462		 *      } );
11463		 *    } );
11464		 *
11465		 *  @example
11466		 *    // Individual cell data
11467		 *    $(document).ready(function() {
11468		 *      oTable = $('#example').dataTable();
11469		 *
11470		 *      oTable.$('td').click( function () {
11471		 *        var sData = oTable.fnGetData( this );
11472		 *        alert( 'The cell clicked on had the value of '+sData );
11473		 *      } );
11474		 *    } );
11475		 */
11476		this.fnGetData = function( src, col )
11477		{
11478			var api = this.api( true );
11479		
11480			if ( src !== undefined ) {
11481				var type = src.nodeName ? src.nodeName.toLowerCase() : '';
11482		
11483				return col !== undefined || type == 'td' || type == 'th' ?
11484					api.cell( src, col ).data() :
11485					api.row( src ).data() || null;
11486			}
11487		
11488			return api.data().toArray();
11489		};
11490		
11491		
11492		/**
11493		 * Get an array of the TR nodes that are used in the table's body. Note that you will
11494		 * typically want to use the '$' API method in preference to this as it is more
11495		 * flexible.
11496		 *  @param {int} [iRow] Optional row index for the TR element you want
11497		 *  @returns {array|node} If iRow is undefined, returns an array of all TR elements
11498		 *    in the table's body, or iRow is defined, just the TR element requested.
11499		 *  @dtopt API
11500		 *  @deprecated Since v1.10
11501		 *
11502		 *  @example
11503		 *    $(document).ready(function() {
11504		 *      var oTable = $('#example').dataTable();
11505		 *
11506		 *      // Get the nodes from the table
11507		 *      var nNodes = oTable.fnGetNodes( );
11508		 *    } );
11509		 */
11510		this.fnGetNodes = function( iRow )
11511		{
11512			var api = this.api( true );
11513		
11514			return iRow !== undefined ?
11515				api.row( iRow ).node() :
11516				api.rows().nodes().flatten().toArray();
11517		};
11518		
11519		
11520		/**
11521		 * Get the array indexes of a particular cell from it's DOM element
11522		 * and column index including hidden columns
11523		 *  @param {node} node this can either be a TR, TD or TH in the table's body
11524		 *  @returns {int} If nNode is given as a TR, then a single index is returned, or
11525		 *    if given as a cell, an array of [row index, column index (visible),
11526		 *    column index (all)] is given.
11527		 *  @dtopt API
11528		 *  @deprecated Since v1.10
11529		 *
11530		 *  @example
11531		 *    $(document).ready(function() {
11532		 *      $('#example tbody td').click( function () {
11533		 *        // Get the position of the current data from the node
11534		 *        var aPos = oTable.fnGetPosition( this );
11535		 *
11536		 *        // Get the data array for this row
11537		 *        var aData = oTable.fnGetData( aPos[0] );
11538		 *
11539		 *        // Update the data array and return the value
11540		 *        aData[ aPos[1] ] = 'clicked';
11541		 *        this.innerHTML = 'clicked';
11542		 *      } );
11543		 *
11544		 *      // Init DataTables
11545		 *      oTable = $('#example').dataTable();
11546		 *    } );
11547		 */
11548		this.fnGetPosition = function( node )
11549		{
11550			var api = this.api( true );
11551			var nodeName = node.nodeName.toUpperCase();
11552		
11553			if ( nodeName == 'TR' ) {
11554				return api.row( node ).index();
11555			}
11556			else if ( nodeName == 'TD' || nodeName == 'TH' ) {
11557				var cell = api.cell( node ).index();
11558		
11559				return [
11560					cell.row,
11561					cell.columnVisible,
11562					cell.column
11563				];
11564			}
11565			return null;
11566		};
11567		
11568		
11569		/**
11570		 * Check to see if a row is 'open' or not.
11571		 *  @param {node} nTr the table row to check
11572		 *  @returns {boolean} true if the row is currently open, false otherwise
11573		 *  @dtopt API
11574		 *  @deprecated Since v1.10
11575		 *
11576		 *  @example
11577		 *    $(document).ready(function() {
11578		 *      var oTable;
11579		 *
11580		 *      // 'open' an information row when a row is clicked on
11581		 *      $('#example tbody tr').click( function () {
11582		 *        if ( oTable.fnIsOpen(this) ) {
11583		 *          oTable.fnClose( this );
11584		 *        } else {
11585		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
11586		 *        }
11587		 *      } );
11588		 *
11589		 *      oTable = $('#example').dataTable();
11590		 *    } );
11591		 */
11592		this.fnIsOpen = function( nTr )
11593		{
11594			return this.api( true ).row( nTr ).child.isShown();
11595		};
11596		
11597		
11598		/**
11599		 * This function will place a new row directly after a row which is currently
11600		 * on display on the page, with the HTML contents that is passed into the
11601		 * function. This can be used, for example, to ask for confirmation that a
11602		 * particular record should be deleted.
11603		 *  @param {node} nTr The table row to 'open'
11604		 *  @param {string|node|jQuery} mHtml The HTML to put into the row
11605		 *  @param {string} sClass Class to give the new TD cell
11606		 *  @returns {node} The row opened. Note that if the table row passed in as the
11607		 *    first parameter, is not found in the table, this method will silently
11608		 *    return.
11609		 *  @dtopt API
11610		 *  @deprecated Since v1.10
11611		 *
11612		 *  @example
11613		 *    $(document).ready(function() {
11614		 *      var oTable;
11615		 *
11616		 *      // 'open' an information row when a row is clicked on
11617		 *      $('#example tbody tr').click( function () {
11618		 *        if ( oTable.fnIsOpen(this) ) {
11619		 *          oTable.fnClose( this );
11620		 *        } else {
11621		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
11622		 *        }
11623		 *      } );
11624		 *
11625		 *      oTable = $('#example').dataTable();
11626		 *    } );
11627		 */
11628		this.fnOpen = function( nTr, mHtml, sClass )
11629		{
11630			return this.api( true )
11631				.row( nTr )
11632				.child( mHtml, sClass )
11633				.show()
11634				.child()[0];
11635		};
11636		
11637		
11638		/**
11639		 * Change the pagination - provides the internal logic for pagination in a simple API
11640		 * function. With this function you can have a DataTables table go to the next,
11641		 * previous, first or last pages.
11642		 *  @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
11643		 *    or page number to jump to (integer), note that page 0 is the first page.
11644		 *  @param {bool} [bRedraw=true] Redraw the table or not
11645		 *  @dtopt API
11646		 *  @deprecated Since v1.10
11647		 *
11648		 *  @example
11649		 *    $(document).ready(function() {
11650		 *      var oTable = $('#example').dataTable();
11651		 *      oTable.fnPageChange( 'next' );
11652		 *    } );
11653		 */
11654		this.fnPageChange = function ( mAction, bRedraw )
11655		{
11656			var api = this.api( true ).page( mAction );
11657		
11658			if ( bRedraw === undefined || bRedraw ) {
11659				api.draw(false);
11660			}
11661		};
11662		
11663		
11664		/**
11665		 * Show a particular column
11666		 *  @param {int} iCol The column whose display should be changed
11667		 *  @param {bool} bShow Show (true) or hide (false) the column
11668		 *  @param {bool} [bRedraw=true] Redraw the table or not
11669		 *  @dtopt API
11670		 *  @deprecated Since v1.10
11671		 *
11672		 *  @example
11673		 *    $(document).ready(function() {
11674		 *      var oTable = $('#example').dataTable();
11675		 *
11676		 *      // Hide the second column after initialisation
11677		 *      oTable.fnSetColumnVis( 1, false );
11678		 *    } );
11679		 */
11680		this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
11681		{
11682			var api = this.api( true ).column( iCol ).visible( bShow );
11683		
11684			if ( bRedraw === undefined || bRedraw ) {
11685				api.columns.adjust().draw();
11686			}
11687		};
11688		
11689		
11690		/**
11691		 * Get the settings for a particular table for external manipulation
11692		 *  @returns {object} DataTables settings object. See
11693		 *    {@link DataTable.models.oSettings}
11694		 *  @dtopt API
11695		 *  @deprecated Since v1.10
11696		 *
11697		 *  @example
11698		 *    $(document).ready(function() {
11699		 *      var oTable = $('#example').dataTable();
11700		 *      var oSettings = oTable.fnSettings();
11701		 *
11702		 *      // Show an example parameter from the settings
11703		 *      alert( oSettings._iDisplayStart );
11704		 *    } );
11705		 */
11706		this.fnSettings = function()
11707		{
11708			return _fnSettingsFromNode( this[_ext.iApiIndex] );
11709		};
11710		
11711		
11712		/**
11713		 * Sort the table by a particular column
11714		 *  @param {int} iCol the data index to sort on. Note that this will not match the
11715		 *    'display index' if you have hidden data entries
11716		 *  @dtopt API
11717		 *  @deprecated Since v1.10
11718		 *
11719		 *  @example
11720		 *    $(document).ready(function() {
11721		 *      var oTable = $('#example').dataTable();
11722		 *
11723		 *      // Sort immediately with columns 0 and 1
11724		 *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
11725		 *    } );
11726		 */
11727		this.fnSort = function( aaSort )
11728		{
11729			this.api( true ).order( aaSort ).draw();
11730		};
11731		
11732		
11733		/**
11734		 * Attach a sort listener to an element for a given column
11735		 *  @param {node} nNode the element to attach the sort listener to
11736		 *  @param {int} iColumn the column that a click on this node will sort on
11737		 *  @param {function} [fnCallback] callback function when sort is run
11738		 *  @dtopt API
11739		 *  @deprecated Since v1.10
11740		 *
11741		 *  @example
11742		 *    $(document).ready(function() {
11743		 *      var oTable = $('#example').dataTable();
11744		 *
11745		 *      // Sort on column 1, when 'sorter' is clicked on
11746		 *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
11747		 *    } );
11748		 */
11749		this.fnSortListener = function( nNode, iColumn, fnCallback )
11750		{
11751			this.api( true ).order.listener( nNode, iColumn, fnCallback );
11752		};
11753		
11754		
11755		/**
11756		 * Update a table cell or row - this method will accept either a single value to
11757		 * update the cell with, an array of values with one element for each column or
11758		 * an object in the same format as the original data source. The function is
11759		 * self-referencing in order to make the multi column updates easier.
11760		 *  @param {object|array|string} mData Data to update the cell/row with
11761		 *  @param {node|int} mRow TR element you want to update or the aoData index
11762		 *  @param {int} [iColumn] The column to update, give as null or undefined to
11763		 *    update a whole row.
11764		 *  @param {bool} [bRedraw=true] Redraw the table or not
11765		 *  @param {bool} [bAction=true] Perform pre-draw actions or not
11766		 *  @returns {int} 0 on success, 1 on error
11767		 *  @dtopt API
11768		 *  @deprecated Since v1.10
11769		 *
11770		 *  @example
11771		 *    $(document).ready(function() {
11772		 *      var oTable = $('#example').dataTable();
11773		 *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
11774		 *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
11775		 *    } );
11776		 */
11777		this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
11778		{
11779			var api = this.api( true );
11780		
11781			if ( iColumn === undefined || iColumn === null ) {
11782				api.row( mRow ).data( mData );
11783			}
11784			else {
11785				api.cell( mRow, iColumn ).data( mData );
11786			}
11787		
11788			if ( bAction === undefined || bAction ) {
11789				api.columns.adjust();
11790			}
11791		
11792			if ( bRedraw === undefined || bRedraw ) {
11793				api.draw();
11794			}
11795			return 0;
11796		};
11797		
11798		
11799		/**
11800		 * Provide a common method for plug-ins to check the version of DataTables being used, in order
11801		 * to ensure compatibility.
11802		 *  @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
11803		 *    formats "X" and "X.Y" are also acceptable.
11804		 *  @returns {boolean} true if this version of DataTables is greater or equal to the required
11805		 *    version, or false if this version of DataTales is not suitable
11806		 *  @method
11807		 *  @dtopt API
11808		 *  @deprecated Since v1.10
11809		 *
11810		 *  @example
11811		 *    $(document).ready(function() {
11812		 *      var oTable = $('#example').dataTable();
11813		 *      alert( oTable.fnVersionCheck( '1.9.0' ) );
11814		 *    } );
11815		 */
11816		this.fnVersionCheck = _ext.fnVersionCheck;
11817		
vendor: 19,922 bytes, lines 11818-12488
11818
11819		var _that = this;
11820		var emptyInit = options === undefined;
11821		var len = this.length;
11822
11823		if ( emptyInit ) {
11824			options = {};
11825		}
11826
11827		this.oApi = this.internal = _ext.internal;
11828
11829		// Extend with old style plug-in API methods
11830		for ( var fn in DataTable.ext.internal ) {
11831			if ( fn ) {
11832				this[fn] = _fnExternApiFunc(fn);
11833			}
11834		}
11835
11836		this.each(function() {
11837			// For each initialisation we want to give it a clean initialisation
11838			// object that can be bashed around
11839			var o = {};
11840			var oInit = len > 1 ? // optimisation for single table case
11841				_fnExtend( o, options, true ) :
11842				options;
11843
11844			/*global oInit,_that,emptyInit*/
11845			var i=0, iLen, j, jLen, k, kLen;
11846			var sId = this.getAttribute( 'id' );
11847			var bInitHandedOff = false;
11848			var defaults = DataTable.defaults;
11849			var $this = $(this);
11850			
11851			
11852			/* Sanity check */
11853			if ( this.nodeName.toLowerCase() != 'table' )
11854			{
11855				_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
11856				return;
11857			}
11858			
11859			/* Backwards compatibility for the defaults */
11860			_fnCompatOpts( defaults );
11861			_fnCompatCols( defaults.column );
11862			
11863			/* Convert the camel-case defaults to Hungarian */
11864			_fnCamelToHungarian( defaults, defaults, true );
11865			_fnCamelToHungarian( defaults.column, defaults.column, true );
11866			
11867			/* Setting up the initialisation object */
11868			_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true );
11869			
11870			
11871			
11872			/* Check to see if we are re-initialising a table */
11873			var allSettings = DataTable.settings;
11874			for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
11875			{
11876				var s = allSettings[i];
11877			
11878				/* Base check on table node */
11879				if (
11880					s.nTable == this ||
11881					(s.nTHead && s.nTHead.parentNode == this) ||
11882					(s.nTFoot && s.nTFoot.parentNode == this)
11883				) {
11884					var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
11885					var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
11886			
11887					if ( emptyInit || bRetrieve )
11888					{
11889						return s.oInstance;
11890					}
11891					else if ( bDestroy )
11892					{
11893						s.oInstance.fnDestroy();
11894						break;
11895					}
11896					else
11897					{
11898						_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
11899						return;
11900					}
11901				}
11902			
11903				/* If the element we are initialising has the same ID as a table which was previously
11904				 * initialised, but the table nodes don't match (from before) then we destroy the old
11905				 * instance by simply deleting it. This is under the assumption that the table has been
11906				 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
11907				 */
11908				if ( s.sTableId == this.id )
11909				{
11910					allSettings.splice( i, 1 );
11911					break;
11912				}
11913			}
11914			
11915			/* Ensure the table has an ID - required for accessibility */
11916			if ( sId === null || sId === "" )
11917			{
11918				sId = "DataTables_Table_"+(DataTable.ext._unique++);
11919				this.id = sId;
11920			}
11921			
11922			/* Create the settings object for this table and set some of the default parameters */
11923			var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
11924				"sDestroyWidth": $this[0].style.width,
11925				"sInstance":     sId,
11926				"sTableId":      sId
11927			} );
11928			oSettings.nTable = this;
11929			oSettings.oApi   = _that.internal;
11930			oSettings.oInit  = oInit;
11931			
11932			allSettings.push( oSettings );
11933			
11934			// Need to add the instance after the instance after the settings object has been added
11935			// to the settings array, so we can self reference the table instance if more than one
11936			oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
11937			
11938			// Backwards compatibility, before we apply all the defaults
11939			_fnCompatOpts( oInit );
11940			_fnLanguageCompat( oInit.oLanguage );
11941			
11942			// If the length menu is given, but the init display length is not, use the length menu
11943			if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
11944			{
11945				oInit.iDisplayLength = Array.isArray( oInit.aLengthMenu[0] ) ?
11946					oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
11947			}
11948			
11949			// Apply the defaults and init options to make a single init object will all
11950			// options defined from defaults and instance options.
11951			oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
11952			
11953			
11954			// Map the initialisation options onto the settings object
11955			_fnMap( oSettings.oFeatures, oInit, [
11956				"bPaginate",
11957				"bLengthChange",
11958				"bFilter",
11959				"bSort",
11960				"bSortMulti",
11961				"bInfo",
11962				"bProcessing",
11963				"bAutoWidth",
11964				"bSortClasses",
11965				"bServerSide",
11966				"bDeferRender"
11967			] );
11968			_fnMap( oSettings, oInit, [
11969				"asStripeClasses",
11970				"ajax",
11971				"fnServerData",
11972				"fnFormatNumber",
11973				"sServerMethod",
11974				"aaSorting",
11975				"aaSortingFixed",
11976				"aLengthMenu",
11977				"sPaginationType",
11978				"sAjaxSource",
11979				"sAjaxDataProp",
11980				"iStateDuration",
11981				"sDom",
11982				"bSortCellsTop",
11983				"iTabIndex",
11984				"fnStateLoadCallback",
11985				"fnStateSaveCallback",
11986				"renderer",
11987				"searchDelay",
11988				"rowId",
11989				[ "iCookieDuration", "iStateDuration" ], // backwards compat
11990				[ "oSearch", "oPreviousSearch" ],
11991				[ "aoSearchCols", "aoPreSearchCols" ],
11992				[ "iDisplayLength", "_iDisplayLength" ]
11993			] );
11994			_fnMap( oSettings.oScroll, oInit, [
11995				[ "sScrollX", "sX" ],
11996				[ "sScrollXInner", "sXInner" ],
11997				[ "sScrollY", "sY" ],
11998				[ "bScrollCollapse", "bCollapse" ]
11999			] );
12000			_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
12001			
12002			/* Callback functions which are array driven */
12003			_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );
12004			_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );
12005			_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );
12006			_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );
12007			_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );
12008			_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );
12009			_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );
12010			_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );
12011			_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );
12012			_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );
12013			_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );
12014			
12015			oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
12016			
12017			/* Browser support detection */
12018			_fnBrowserDetect( oSettings );
12019			
12020			var oClasses = oSettings.oClasses;
12021			
12022			$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
12023			$this.addClass( oClasses.sTable );
12024			
12025			
12026			if ( oSettings.iInitDisplayStart === undefined )
12027			{
12028				/* Display start point, taking into account the save saving */
12029				oSettings.iInitDisplayStart = oInit.iDisplayStart;
12030				oSettings._iDisplayStart = oInit.iDisplayStart;
12031			}
12032			
12033			if ( oInit.iDeferLoading !== null )
12034			{
12035				oSettings.bDeferLoading = true;
12036				var tmp = Array.isArray( oInit.iDeferLoading );
12037				oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
12038				oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
12039			}
12040			
12041			/* Language definitions */
12042			var oLanguage = oSettings.oLanguage;
12043			$.extend( true, oLanguage, oInit.oLanguage );
12044			
12045			if ( oLanguage.sUrl )
12046			{
12047				/* Get the language definitions from a file - because this Ajax call makes the language
12048				 * get async to the remainder of this function we use bInitHandedOff to indicate that
12049				 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
12050				 */
12051				$.ajax( {
12052					dataType: 'json',
12053					url: oLanguage.sUrl,
12054					success: function ( json ) {
12055						_fnCamelToHungarian( defaults.oLanguage, json );
12056						_fnLanguageCompat( json );
12057						$.extend( true, oLanguage, json );
12058			
12059						_fnCallbackFire( oSettings, null, 'i18n', [oSettings]);
12060						_fnInitialise( oSettings );
12061					},
12062					error: function () {
12063						// Error occurred loading language file, continue on as best we can
12064						_fnInitialise( oSettings );
12065					}
12066				} );
12067				bInitHandedOff = true;
12068			}
12069			else {
12070				_fnCallbackFire( oSettings, null, 'i18n', [oSettings]);
12071			}
12072			
12073			/*
12074			 * Stripes
12075			 */
12076			if ( oInit.asStripeClasses === null )
12077			{
12078				oSettings.asStripeClasses =[
12079					oClasses.sStripeOdd,
12080					oClasses.sStripeEven
12081				];
12082			}
12083			
12084			/* Remove row stripe classes if they are already on the table row */
12085			var stripeClasses = oSettings.asStripeClasses;
12086			var rowOne = $this.children('tbody').find('tr').eq(0);
12087			if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
12088				return rowOne.hasClass(el);
12089			} ) ) !== -1 ) {
12090				$('tbody tr', this).removeClass( stripeClasses.join(' ') );
12091				oSettings.asDestroyStripes = stripeClasses.slice();
12092			}
12093			
12094			/*
12095			 * Columns
12096			 * See if we should load columns automatically or use defined ones
12097			 */
12098			var anThs = [];
12099			var aoColumnsInit;
12100			var nThead = this.getElementsByTagName('thead');
12101			if ( nThead.length !== 0 )
12102			{
12103				_fnDetectHeader( oSettings.aoHeader, nThead[0] );
12104				anThs = _fnGetUniqueThs( oSettings );
12105			}
12106			
12107			/* If not given a column array, generate one with nulls */
12108			if ( oInit.aoColumns === null )
12109			{
12110				aoColumnsInit = [];
12111				for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
12112				{
12113					aoColumnsInit.push( null );
12114				}
12115			}
12116			else
12117			{
12118				aoColumnsInit = oInit.aoColumns;
12119			}
12120			
12121			/* Add the columns */
12122			for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
12123			{
12124				_fnAddColumn( oSettings, anThs ? anThs[i] : null );
12125			}
12126			
12127			/* Apply the column definitions */
12128			_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
12129				_fnColumnOptions( oSettings, iCol, oDef );
12130			} );
12131			
12132			/* HTML5 attribute detection - build an mData object automatically if the
12133			 * attributes are found
12134			 */
12135			if ( rowOne.length ) {
12136				var a = function ( cell, name ) {
12137					return cell.getAttribute( 'data-'+name ) !== null ? name : null;
12138				};
12139			
12140				$( rowOne[0] ).children('th, td').each( function (i, cell) {
12141					var col = oSettings.aoColumns[i];
12142			
12143					if ( col.mData === i ) {
12144						var sort = a( cell, 'sort' ) || a( cell, 'order' );
12145						var filter = a( cell, 'filter' ) || a( cell, 'search' );
12146			
12147						if ( sort !== null || filter !== null ) {
12148							col.mData = {
12149								_:      i+'.display',
12150								sort:   sort !== null   ? i+'.@data-'+sort   : undefined,
12151								type:   sort !== null   ? i+'.@data-'+sort   : undefined,
12152								filter: filter !== null ? i+'.@data-'+filter : undefined
12153							};
12154			
12155							_fnColumnOptions( oSettings, i );
12156						}
12157					}
12158				} );
12159			}
12160			
12161			var features = oSettings.oFeatures;
12162			var loadedInit = function () {
12163				/*
12164				 * Sorting
12165				 * @todo For modularisation (1.11) this needs to do into a sort start up handler
12166				 */
12167			
12168				// If aaSorting is not defined, then we use the first indicator in asSorting
12169				// in case that has been altered, so the default sort reflects that option
12170				if ( oInit.aaSorting === undefined ) {
12171					var sorting = oSettings.aaSorting;
12172					for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
12173						sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
12174					}
12175				}
12176			
12177				/* Do a first pass on the sorting classes (allows any size changes to be taken into
12178				 * account, and also will apply sorting disabled classes if disabled
12179				 */
12180				_fnSortingClasses( oSettings );
12181			
12182				if ( features.bSort ) {
12183					_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
12184						if ( oSettings.bSorted ) {
12185							var aSort = _fnSortFlatten( oSettings );
12186							var sortedColumns = {};
12187			
12188							$.each( aSort, function (i, val) {
12189								sortedColumns[ val.src ] = val.dir;
12190							} );
12191			
12192							_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
12193							_fnSortAria( oSettings );
12194						}
12195					} );
12196				}
12197			
12198				_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
12199					if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
12200						_fnSortingClasses( oSettings );
12201					}
12202				}, 'sc' );
12203			
12204			
12205				/*
12206				 * Final init
12207				 * Cache the header, body and footer as required, creating them if needed
12208				 */
12209			
12210				// Work around for Webkit bug 83867 - store the caption-side before removing from doc
12211				var captions = $this.children('caption').each( function () {
12212					this._captionSide = $(this).css('caption-side');
12213				} );
12214			
12215				var thead = $this.children('thead');
12216				if ( thead.length === 0 ) {
12217					thead = $('<thead/>').appendTo($this);
12218				}
12219				oSettings.nTHead = thead[0];
12220			
12221				var tbody = $this.children('tbody');
12222				if ( tbody.length === 0 ) {
12223					tbody = $('<tbody/>').insertAfter(thead);
12224				}
12225				oSettings.nTBody = tbody[0];
12226			
12227				var tfoot = $this.children('tfoot');
12228				if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
12229					// If we are a scrolling table, and no footer has been given, then we need to create
12230					// a tfoot element for the caption element to be appended to
12231					tfoot = $('<tfoot/>').appendTo($this);
12232				}
12233			
12234				if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
12235					$this.addClass( oClasses.sNoFooter );
12236				}
12237				else if ( tfoot.length > 0 ) {
12238					oSettings.nTFoot = tfoot[0];
12239					_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
12240				}
12241			
12242				/* Check if there is data passing into the constructor */
12243				if ( oInit.aaData ) {
12244					for ( i=0 ; i<oInit.aaData.length ; i++ ) {
12245						_fnAddData( oSettings, oInit.aaData[ i ] );
12246					}
12247				}
12248				else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
12249					/* Grab the data from the page - only do this when deferred loading or no Ajax
12250					 * source since there is no point in reading the DOM data if we are then going
12251					 * to replace it with Ajax data
12252					 */
12253					_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
12254				}
12255			
12256				/* Copy the data index array */
12257				oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
12258			
12259				/* Initialisation complete - table can be drawn */
12260				oSettings.bInitialised = true;
12261			
12262				/* Check if we need to initialise the table (it might not have been handed off to the
12263				 * language processor)
12264				 */
12265				if ( bInitHandedOff === false ) {
12266					_fnInitialise( oSettings );
12267				}
12268			};
12269			
12270			/* Must be done after everything which can be overridden by the state saving! */
12271			_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
12272			
12273			if ( oInit.bStateSave )
12274			{
12275				features.bStateSave = true;
12276				_fnLoadState( oSettings, oInit, loadedInit );
12277			}
12278			else {
12279				loadedInit();
12280			}
12281			
12282		} );
12283		_that = null;
12284		return this;
12285	};
12286
12287	
12288	/*
12289	 * It is useful to have variables which are scoped locally so only the
12290	 * DataTables functions can access them and they don't leak into global space.
12291	 * At the same time these functions are often useful over multiple files in the
12292	 * core and API, so we list, or at least document, all variables which are used
12293	 * by DataTables as private variables here. This also ensures that there is no
12294	 * clashing of variable names and that they can easily referenced for reuse.
12295	 */
12296	
12297	
12298	// Defined else where
12299	//  _selector_run
12300	//  _selector_opts
12301	//  _selector_first
12302	//  _selector_row_indexes
12303	
12304	var _ext; // DataTable.ext
12305	var _Api; // DataTable.Api
12306	var _api_register; // DataTable.Api.register
12307	var _api_registerPlural; // DataTable.Api.registerPlural
12308	
12309	var _re_dic = {};
12310	var _re_new_lines = /[\r\n\u2028]/g;
12311	var _re_html = /<.*?>/g;
12312	
12313	// This is not strict ISO8601 - Date.parse() is quite lax, although
12314	// implementations differ between browsers.
12315	var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
12316	
12317	// Escape regular expression special characters
12318	var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
12319	
12320	// http://en.wikipedia.org/wiki/Foreign_exchange_market
12321	// - \u20BD - Russian ruble.
12322	// - \u20a9 - South Korean Won
12323	// - \u20BA - Turkish Lira
12324	// - \u20B9 - Indian Rupee
12325	// - R - Brazil (R$) and South Africa
12326	// - fr - Swiss Franc
12327	// - kr - Swedish krona, Norwegian krone and Danish krone
12328	// - \u2009 is thin space and \u202F is narrow no-break space, both used in many
12329	// - Ƀ - Bitcoin
12330	// - Ξ - Ethereum
12331	//   standards as thousands separators.
12332	var _re_formatted_numeric = /['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi;
12333	
12334	
12335	var _empty = function ( d ) {
12336		return !d || d === true || d === '-' ? true : false;
12337	};
12338	
12339	
12340	var _intVal = function ( s ) {
12341		var integer = parseInt( s, 10 );
12342		return !isNaN(integer) && isFinite(s) ? integer : null;
12343	};
12344	
12345	// Convert from a formatted number with characters other than `.` as the
12346	// decimal place, to a Javascript number
12347	var _numToDecimal = function ( num, decimalPoint ) {
12348		// Cache created regular expressions for speed as this function is called often
12349		if ( ! _re_dic[ decimalPoint ] ) {
12350			_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
12351		}
12352		return typeof num === 'string' && decimalPoint !== '.' ?
12353			num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
12354			num;
12355	};
12356	
12357	
12358	var _isNumber = function ( d, decimalPoint, formatted ) {
12359		var strType = typeof d === 'string';
12360	
12361		// If empty return immediately so there must be a number if it is a
12362		// formatted string (this stops the string "k", or "kr", etc being detected
12363		// as a formatted number for currency
12364		if ( _empty( d ) ) {
12365			return true;
12366		}
12367	
12368		if ( decimalPoint && strType ) {
12369			d = _numToDecimal( d, decimalPoint );
12370		}
12371	
12372		if ( formatted && strType ) {
12373			d = d.replace( _re_formatted_numeric, '' );
12374		}
12375	
12376		return !isNaN( parseFloat(d) ) && isFinite( d );
12377	};
12378	
12379	
12380	// A string without HTML in it can be considered to be HTML still
12381	var _isHtml = function ( d ) {
12382		return _empty( d ) || typeof d === 'string';
12383	};
12384	
12385	
12386	var _htmlNumeric = function ( d, decimalPoint, formatted ) {
12387		if ( _empty( d ) ) {
12388			return true;
12389		}
12390	
12391		var html = _isHtml( d );
12392		return ! html ?
12393			null :
12394			_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
12395				true :
12396				null;
12397	};
12398	
12399	
12400	var _pluck = function ( a, prop, prop2 ) {
12401		var out = [];
12402		var i=0, ien=a.length;
12403	
12404		// Could have the test in the loop for slightly smaller code, but speed
12405		// is essential here
12406		if ( prop2 !== undefined ) {
12407			for ( ; i<ien ; i++ ) {
12408				if ( a[i] && a[i][ prop ] ) {
12409					out.push( a[i][ prop ][ prop2 ] );
12410				}
12411			}
12412		}
12413		else {
12414			for ( ; i<ien ; i++ ) {
12415				if ( a[i] ) {
12416					out.push( a[i][ prop ] );
12417				}
12418			}
12419		}
12420	
12421		return out;
12422	};
12423	
12424	
12425	// Basically the same as _pluck, but rather than looping over `a` we use `order`
12426	// as the indexes to pick from `a`
12427	var _pluck_order = function ( a, order, prop, prop2 )
12428	{
12429		var out = [];
12430		var i=0, ien=order.length;
12431	
12432		// Could have the test in the loop for slightly smaller code, but speed
12433		// is essential here
12434		if ( prop2 !== undefined ) {
12435			for ( ; i<ien ; i++ ) {
12436				if ( a[ order[i] ][ prop ] ) {
12437					out.push( a[ order[i] ][ prop ][ prop2 ] );
12438				}
12439			}
12440		}
12441		else {
12442			for ( ; i<ien ; i++ ) {
12443				out.push( a[ order[i] ][ prop ] );
12444			}
12445		}
12446	
12447		return out;
12448	};
12449	
12450	
12451	var _range = function ( len, start )
12452	{
12453		var out = [];
12454		var end;
12455	
12456		if ( start === undefined ) {
12457			start = 0;
12458			end = len;
12459		}
12460		else {
12461			end = start;
12462			start = len;
12463		}
12464	
12465		for ( var i=start ; i<end ; i++ ) {
12466			out.push( i );
12467		}
12468	
12469		return out;
12470	};
12471	
12472	
12473	var _removeEmpty = function ( a )
12474	{
12475		var out = [];
12476	
12477		for ( var i=0, ien=a.length ; i<ien ; i++ ) {
12478			if ( a[i] ) { // careful - will remove all falsy values!
12479				out.push( a[i] );
12480			}
12481		}
12482	
12483		return out;
12484	};
12485	
12486	
12487	var _stripHtml = function ( d ) {
12488		return d.replace( _re_html, '' );
vendor: 10,574 bytes, lines 12488-12862
12488
12489	};
12490	
12491	
12492	/**
12493	 * Determine if all values in the array are unique. This means we can short
12494	 * cut the _unique method at the cost of a single loop. A sorted array is used
12495	 * to easily check the values.
12496	 *
12497	 * @param  {array} src Source array
12498	 * @return {boolean} true if all unique, false otherwise
12499	 * @ignore
12500	 */
12501	var _areAllUnique = function ( src ) {
12502		if ( src.length < 2 ) {
12503			return true;
12504		}
12505	
12506		var sorted = src.slice().sort();
12507		var last = sorted[0];
12508	
12509		for ( var i=1, ien=sorted.length ; i<ien ; i++ ) {
12510			if ( sorted[i] === last ) {
12511				return false;
12512			}
12513	
12514			last = sorted[i];
12515		}
12516	
12517		return true;
12518	};
12519	
12520	
12521	/**
12522	 * Find the unique elements in a source array.
12523	 *
12524	 * @param  {array} src Source array
12525	 * @return {array} Array of unique items
12526	 * @ignore
12527	 */
12528	var _unique = function ( src )
12529	{
12530		if ( _areAllUnique( src ) ) {
12531			return src.slice();
12532		}
12533	
12534		// A faster unique method is to use object keys to identify used values,
12535		// but this doesn't work with arrays or objects, which we must also
12536		// consider. See jsperf.com/compare-array-unique-versions/4 for more
12537		// information.
12538		var
12539			out = [],
12540			val,
12541			i, ien=src.length,
12542			j, k=0;
12543	
12544		again: for ( i=0 ; i<ien ; i++ ) {
12545			val = src[i];
12546	
12547			for ( j=0 ; j<k ; j++ ) {
12548				if ( out[j] === val ) {
12549					continue again;
12550				}
12551			}
12552	
12553			out.push( val );
12554			k++;
12555		}
12556	
12557		return out;
12558	};
12559	
12560	// Surprisingly this is faster than [].concat.apply
12561	// https://jsperf.com/flatten-an-array-loop-vs-reduce/2
12562	var _flatten = function (out, val) {
12563		if (Array.isArray(val)) {
12564			for (var i=0 ; i<val.length ; i++) {
12565				_flatten(out, val[i]);
12566			}
12567		}
12568		else {
12569			out.push(val);
12570		}
12571	  
12572		return out;
12573	}
12574	
12575	var _includes = function (search, start) {
12576		if (start === undefined) {
12577			start = 0;
12578		}
12579	
12580		return this.indexOf(search, start) !== -1;	
12581	};
12582	
12583	// Array.isArray polyfill.
12584	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
12585	if (! Array.isArray) {
12586	    Array.isArray = function(arg) {
12587	        return Object.prototype.toString.call(arg) === '[object Array]';
12588	    };
12589	}
12590	
12591	if (! Array.prototype.includes) {
12592		Array.prototype.includes = _includes;
12593	}
12594	
12595	// .trim() polyfill
12596	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim
12597	if (!String.prototype.trim) {
12598	  String.prototype.trim = function () {
12599	    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
12600	  };
12601	}
12602	
12603	if (! String.prototype.includes) {
12604		String.prototype.includes = _includes;
12605	}
12606	
12607	/**
12608	 * DataTables utility methods
12609	 * 
12610	 * This namespace provides helper methods that DataTables uses internally to
12611	 * create a DataTable, but which are not exclusively used only for DataTables.
12612	 * These methods can be used by extension authors to save the duplication of
12613	 * code.
12614	 *
12615	 *  @namespace
12616	 */
12617	DataTable.util = {
12618		/**
12619		 * Throttle the calls to a function. Arguments and context are maintained
12620		 * for the throttled function.
12621		 *
12622		 * @param {function} fn Function to be called
12623		 * @param {integer} freq Call frequency in mS
12624		 * @return {function} Wrapped function
12625		 */
12626		throttle: function ( fn, freq ) {
12627			var
12628				frequency = freq !== undefined ? freq : 200,
12629				last,
12630				timer;
12631	
12632			return function () {
12633				var
12634					that = this,
12635					now  = +new Date(),
12636					args = arguments;
12637	
12638				if ( last && now < last + frequency ) {
12639					clearTimeout( timer );
12640	
12641					timer = setTimeout( function () {
12642						last = undefined;
12643						fn.apply( that, args );
12644					}, frequency );
12645				}
12646				else {
12647					last = now;
12648					fn.apply( that, args );
12649				}
12650			};
12651		},
12652	
12653	
12654		/**
12655		 * Escape a string such that it can be used in a regular expression
12656		 *
12657		 *  @param {string} val string to escape
12658		 *  @returns {string} escaped string
12659		 */
12660		escapeRegex: function ( val ) {
12661			return val.replace( _re_escape_regex, '\\$1' );
12662		},
12663	
12664		/**
12665		 * Create a function that will write to a nested object or array
12666		 * @param {*} source JSON notation string
12667		 * @returns Write function
12668		 */
12669		set: function ( source ) {
12670			if ( $.isPlainObject( source ) ) {
12671				/* Unlike get, only the underscore (global) option is used for for
12672				 * setting data since we don't know the type here. This is why an object
12673				 * option is not documented for `mData` (which is read/write), but it is
12674				 * for `mRender` which is read only.
12675				 */
12676				return DataTable.util.set( source._ );
12677			}
12678			else if ( source === null ) {
12679				// Nothing to do when the data source is null
12680				return function () {};
12681			}
12682			else if ( typeof source === 'function' ) {
12683				return function (data, val, meta) {
12684					source( data, 'set', val, meta );
12685				};
12686			}
12687			else if ( typeof source === 'string' && (source.indexOf('.') !== -1 ||
12688					  source.indexOf('[') !== -1 || source.indexOf('(') !== -1) )
12689			{
12690				// Like the get, we need to get data from a nested object
12691				var setData = function (data, val, src) {
12692					var a = _fnSplitObjNotation( src ), b;
12693					var aLast = a[a.length-1];
12694					var arrayNotation, funcNotation, o, innerSrc;
12695		
12696					for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) {
12697						// Protect against prototype pollution
12698						if (a[i] === '__proto__' || a[i] === 'constructor') {
12699							throw new Error('Cannot set prototype values');
12700						}
12701		
12702						// Check if we are dealing with an array notation request
12703						arrayNotation = a[i].match(__reArray);
12704						funcNotation = a[i].match(__reFn);
12705		
12706						if ( arrayNotation ) {
12707							a[i] = a[i].replace(__reArray, '');
12708							data[ a[i] ] = [];
12709		
12710							// Get the remainder of the nested object to set so we can recurse
12711							b = a.slice();
12712							b.splice( 0, i+1 );
12713							innerSrc = b.join('.');
12714		
12715							// Traverse each entry in the array setting the properties requested
12716							if ( Array.isArray( val ) ) {
12717								for ( var j=0, jLen=val.length ; j<jLen ; j++ ) {
12718									o = {};
12719									setData( o, val[j], innerSrc );
12720									data[ a[i] ].push( o );
12721								}
12722							}
12723							else {
12724								// We've been asked to save data to an array, but it
12725								// isn't array data to be saved. Best that can be done
12726								// is to just save the value.
12727								data[ a[i] ] = val;
12728							}
12729		
12730							// The inner call to setData has already traversed through the remainder
12731							// of the source and has set the data, thus we can exit here
12732							return;
12733						}
12734						else if ( funcNotation ) {
12735							// Function call
12736							a[i] = a[i].replace(__reFn, '');
12737							data = data[ a[i] ]( val );
12738						}
12739		
12740						// If the nested object doesn't currently exist - since we are
12741						// trying to set the value - create it
12742						if ( data[ a[i] ] === null || data[ a[i] ] === undefined ) {
12743							data[ a[i] ] = {};
12744						}
12745						data = data[ a[i] ];
12746					}
12747		
12748					// Last item in the input - i.e, the actual set
12749					if ( aLast.match(__reFn ) ) {
12750						// Function call
12751						data = data[ aLast.replace(__reFn, '') ]( val );
12752					}
12753					else {
12754						// If array notation is used, we just want to strip it and use the property name
12755						// and assign the value. If it isn't used, then we get the result we want anyway
12756						data[ aLast.replace(__reArray, '') ] = val;
12757					}
12758				};
12759		
12760				return function (data, val) { // meta is also passed in, but not used
12761					return setData( data, val, source );
12762				};
12763			}
12764			else {
12765				// Array or flat object mapping
12766				return function (data, val) { // meta is also passed in, but not used
12767					data[source] = val;
12768				};
12769			}
12770		},
12771	
12772		/**
12773		 * Create a function that will read nested objects from arrays, based on JSON notation
12774		 * @param {*} source JSON notation string
12775		 * @returns Value read
12776		 */
12777		get: function ( source ) {
12778			if ( $.isPlainObject( source ) ) {
12779				// Build an object of get functions, and wrap them in a single call
12780				var o = {};
12781				$.each( source, function (key, val) {
12782					if ( val ) {
12783						o[key] = DataTable.util.get( val );
12784					}
12785				} );
12786		
12787				return function (data, type, row, meta) {
12788					var t = o[type] || o._;
12789					return t !== undefined ?
12790						t(data, type, row, meta) :
12791						data;
12792				};
12793			}
12794			else if ( source === null ) {
12795				// Give an empty string for rendering / sorting etc
12796				return function (data) { // type, row and meta also passed, but not used
12797					return data;
12798				};
12799			}
12800			else if ( typeof source === 'function' ) {
12801				return function (data, type, row, meta) {
12802					return source( data, type, row, meta );
12803				};
12804			}
12805			else if ( typeof source === 'string' && (source.indexOf('.') !== -1 ||
12806					  source.indexOf('[') !== -1 || source.indexOf('(') !== -1) )
12807			{
12808				/* If there is a . in the source string then the data source is in a
12809				 * nested object so we loop over the data for each level to get the next
12810				 * level down. On each loop we test for undefined, and if found immediately
12811				 * return. This allows entire objects to be missing and sDefaultContent to
12812				 * be used if defined, rather than throwing an error
12813				 */
12814				var fetchData = function (data, type, src) {
12815					var arrayNotation, funcNotation, out, innerSrc;
12816		
12817					if ( src !== "" ) {
12818						var a = _fnSplitObjNotation( src );
12819		
12820						for ( var i=0, iLen=a.length ; i<iLen ; i++ ) {
12821							// Check if we are dealing with special notation
12822							arrayNotation = a[i].match(__reArray);
12823							funcNotation = a[i].match(__reFn);
12824		
12825							if ( arrayNotation ) {
12826								// Array notation
12827								a[i] = a[i].replace(__reArray, '');
12828		
12829								// Condition allows simply [] to be passed in
12830								if ( a[i] !== "" ) {
12831									data = data[ a[i] ];
12832								}
12833								out = [];
12834		
12835								// Get the remainder of the nested object to get
12836								a.splice( 0, i+1 );
12837								innerSrc = a.join('.');
12838		
12839								// Traverse each entry in the array getting the properties requested
12840								if ( Array.isArray( data ) ) {
12841									for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
12842										out.push( fetchData( data[j], type, innerSrc ) );
12843									}
12844								}
12845		
12846								// If a string is given in between the array notation indicators, that
12847								// is used to join the strings together, otherwise an array is returned
12848								var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
12849								data = (join==="") ? out : out.join(join);
12850		
12851								// The inner call to fetchData has already traversed through the remainder
12852								// of the source requested, so we exit from the loop
12853								break;
12854							}
12855							else if ( funcNotation ) {
12856								// Function call
12857								a[i] = a[i].replace(__reFn, '');
12858								data = data[ a[i] ]();
12859								continue;
12860							}
12861		
12862							if (
vendor: 20,462 bytes, lines 12862-13567
12862 data === null || data[ a[i] ] === undefined ) {
12863								return undefined;
12864							}
12865	
12866							data = data[ a[i] ];
12867						}
12868					}
12869		
12870					return data;
12871				};
12872		
12873				return function (data, type) { // row and meta also passed, but not used
12874					return fetchData( data, type, source );
12875				};
12876			}
12877			else {
12878				// Array or flat object mapping
12879				return function (data, type) { // row and meta also passed, but not used
12880					return data[source];
12881				};
12882			}
12883		}
12884	};
12885	
12886	
12887	
12888	/**
12889	 * Create a mapping object that allows camel case parameters to be looked up
12890	 * for their Hungarian counterparts. The mapping is stored in a private
12891	 * parameter called `_hungarianMap` which can be accessed on the source object.
12892	 *  @param {object} o
12893	 *  @memberof DataTable#oApi
12894	 */
12895	function _fnHungarianMap ( o )
12896	{
12897		var
12898			hungarian = 'a aa ai ao as b fn i m o s ',
12899			match,
12900			newKey,
12901			map = {};
12902	
12903		$.each( o, function (key, val) {
12904			match = key.match(/^([^A-Z]+?)([A-Z])/);
12905	
12906			if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
12907			{
12908				newKey = key.replace( match[0], match[2].toLowerCase() );
12909				map[ newKey ] = key;
12910	
12911				if ( match[1] === 'o' )
12912				{
12913					_fnHungarianMap( o[key] );
12914				}
12915			}
12916		} );
12917	
12918		o._hungarianMap = map;
12919	}
12920	
12921	
12922	/**
12923	 * Convert from camel case parameters to Hungarian, based on a Hungarian map
12924	 * created by _fnHungarianMap.
12925	 *  @param {object} src The model object which holds all parameters that can be
12926	 *    mapped.
12927	 *  @param {object} user The object to convert from camel case to Hungarian.
12928	 *  @param {boolean} force When set to `true`, properties which already have a
12929	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
12930	 *    won't be.
12931	 *  @memberof DataTable#oApi
12932	 */
12933	function _fnCamelToHungarian ( src, user, force )
12934	{
12935		if ( ! src._hungarianMap ) {
12936			_fnHungarianMap( src );
12937		}
12938	
12939		var hungarianKey;
12940	
12941		$.each( user, function (key, val) {
12942			hungarianKey = src._hungarianMap[ key ];
12943	
12944			if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
12945			{
12946				// For objects, we need to buzz down into the object to copy parameters
12947				if ( hungarianKey.charAt(0) === 'o' )
12948				{
12949					// Copy the camelCase options over to the hungarian
12950					if ( ! user[ hungarianKey ] ) {
12951						user[ hungarianKey ] = {};
12952					}
12953					$.extend( true, user[hungarianKey], user[key] );
12954	
12955					_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
12956				}
12957				else {
12958					user[hungarianKey] = user[ key ];
12959				}
12960			}
12961		} );
12962	}
12963	
12964	
12965	/**
12966	 * Language compatibility - when certain options are given, and others aren't, we
12967	 * need to duplicate the values over, in order to provide backwards compatibility
12968	 * with older language files.
12969	 *  @param {object} oSettings dataTables settings object
12970	 *  @memberof DataTable#oApi
12971	 */
12972	function _fnLanguageCompat( lang )
12973	{
12974		// Note the use of the Hungarian notation for the parameters in this method as
12975		// this is called after the mapping of camelCase to Hungarian
12976		var defaults = DataTable.defaults.oLanguage;
12977	
12978		// Default mapping
12979		var defaultDecimal = defaults.sDecimal;
12980		if ( defaultDecimal ) {
12981			_addNumericSort( defaultDecimal );
12982		}
12983	
12984		if ( lang ) {
12985			var zeroRecords = lang.sZeroRecords;
12986	
12987			// Backwards compatibility - if there is no sEmptyTable given, then use the same as
12988			// sZeroRecords - assuming that is given.
12989			if ( ! lang.sEmptyTable && zeroRecords &&
12990				defaults.sEmptyTable === "No data available in table" )
12991			{
12992				_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
12993			}
12994	
12995			// Likewise with loading records
12996			if ( ! lang.sLoadingRecords && zeroRecords &&
12997				defaults.sLoadingRecords === "Loading..." )
12998			{
12999				_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
13000			}
13001	
13002			// Old parameter name of the thousands separator mapped onto the new
13003			if ( lang.sInfoThousands ) {
13004				lang.sThousands = lang.sInfoThousands;
13005			}
13006	
13007			var decimal = lang.sDecimal;
13008			if ( decimal && defaultDecimal !== decimal ) {
13009				_addNumericSort( decimal );
13010			}
13011		}
13012	}
13013	
13014	
13015	/**
13016	 * Map one parameter onto another
13017	 *  @param {object} o Object to map
13018	 *  @param {*} knew The new parameter name
13019	 *  @param {*} old The old parameter name
13020	 */
13021	var _fnCompatMap = function ( o, knew, old ) {
13022		if ( o[ knew ] !== undefined ) {
13023			o[ old ] = o[ knew ];
13024		}
13025	};
13026	
13027	
13028	/**
13029	 * Provide backwards compatibility for the main DT options. Note that the new
13030	 * options are mapped onto the old parameters, so this is an external interface
13031	 * change only.
13032	 *  @param {object} init Object to map
13033	 */
13034	function _fnCompatOpts ( init )
13035	{
13036		_fnCompatMap( init, 'ordering',      'bSort' );
13037		_fnCompatMap( init, 'orderMulti',    'bSortMulti' );
13038		_fnCompatMap( init, 'orderClasses',  'bSortClasses' );
13039		_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
13040		_fnCompatMap( init, 'order',         'aaSorting' );
13041		_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );
13042		_fnCompatMap( init, 'paging',        'bPaginate' );
13043		_fnCompatMap( init, 'pagingType',    'sPaginationType' );
13044		_fnCompatMap( init, 'pageLength',    'iDisplayLength' );
13045		_fnCompatMap( init, 'searching',     'bFilter' );
13046	
13047		// Boolean initialisation of x-scrolling
13048		if ( typeof init.sScrollX === 'boolean' ) {
13049			init.sScrollX = init.sScrollX ? '100%' : '';
13050		}
13051		if ( typeof init.scrollX === 'boolean' ) {
13052			init.scrollX = init.scrollX ? '100%' : '';
13053		}
13054	
13055		// Column search objects are in an array, so it needs to be converted
13056		// element by element
13057		var searchCols = init.aoSearchCols;
13058	
13059		if ( searchCols ) {
13060			for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
13061				if ( searchCols[i] ) {
13062					_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
13063				}
13064			}
13065		}
13066	}
13067	
13068	
13069	/**
13070	 * Provide backwards compatibility for column options. Note that the new options
13071	 * are mapped onto the old parameters, so this is an external interface change
13072	 * only.
13073	 *  @param {object} init Object to map
13074	 */
13075	function _fnCompatCols ( init )
13076	{
13077		_fnCompatMap( init, 'orderable',     'bSortable' );
13078		_fnCompatMap( init, 'orderData',     'aDataSort' );
13079		_fnCompatMap( init, 'orderSequence', 'asSorting' );
13080		_fnCompatMap( init, 'orderDataType', 'sortDataType' );
13081	
13082		// orderData can be given as an integer
13083		var dataSort = init.aDataSort;
13084		if ( typeof dataSort === 'number' && ! Array.isArray( dataSort ) ) {
13085			init.aDataSort = [ dataSort ];
13086		}
13087	}
13088	
13089	
13090	/**
13091	 * Browser feature detection for capabilities, quirks
13092	 *  @param {object} settings dataTables settings object
13093	 *  @memberof DataTable#oApi
13094	 */
13095	function _fnBrowserDetect( settings )
13096	{
13097		// We don't need to do this every time DataTables is constructed, the values
13098		// calculated are specific to the browser and OS configuration which we
13099		// don't expect to change between initialisations
13100		if ( ! DataTable.__browser ) {
13101			var browser = {};
13102			DataTable.__browser = browser;
13103	
13104			// Scrolling feature / quirks detection
13105			var n = $('<div/>')
13106				.css( {
13107					position: 'fixed',
13108					top: 0,
13109					left: $(window).scrollLeft()*-1, // allow for scrolling
13110					height: 1,
13111					width: 1,
13112					overflow: 'hidden'
13113				} )
13114				.append(
13115					$('<div/>')
13116						.css( {
13117							position: 'absolute',
13118							top: 1,
13119							left: 1,
13120							width: 100,
13121							overflow: 'scroll'
13122						} )
13123						.append(
13124							$('<div/>')
13125								.css( {
13126									width: '100%',
13127									height: 10
13128								} )
13129						)
13130				)
13131				.appendTo( 'body' );
13132	
13133			var outer = n.children();
13134			var inner = outer.children();
13135	
13136			// Numbers below, in order, are:
13137			// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
13138			//
13139			// IE6 XP:                           100 100 100  83
13140			// IE7 Vista:                        100 100 100  83
13141			// IE 8+ Windows:                     83  83 100  83
13142			// Evergreen Windows:                 83  83 100  83
13143			// Evergreen Mac with scrollbars:     85  85 100  85
13144			// Evergreen Mac without scrollbars: 100 100 100 100
13145	
13146			// Get scrollbar width
13147			browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
13148	
13149			// IE6/7 will oversize a width 100% element inside a scrolling element, to
13150			// include the width of the scrollbar, while other browsers ensure the inner
13151			// element is contained without forcing scrolling
13152			browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
13153	
13154			// In rtl text layout, some browsers (most, but not all) will place the
13155			// scrollbar on the left, rather than the right.
13156			browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
13157	
13158			// IE8- don't provide height and width for getBoundingClientRect
13159			browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
13160	
13161			n.remove();
13162		}
13163	
13164		$.extend( settings.oBrowser, DataTable.__browser );
13165		settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
13166	}
13167	
13168	
13169	/**
13170	 * Array.prototype reduce[Right] method, used for browsers which don't support
13171	 * JS 1.6. Done this way to reduce code size, since we iterate either way
13172	 *  @param {object} settings dataTables settings object
13173	 *  @memberof DataTable#oApi
13174	 */
13175	function _fnReduce ( that, fn, init, start, end, inc )
13176	{
13177		var
13178			i = start,
13179			value,
13180			isSet = false;
13181	
13182		if ( init !== undefined ) {
13183			value = init;
13184			isSet = true;
13185		}
13186	
13187		while ( i !== end ) {
13188			if ( ! that.hasOwnProperty(i) ) {
13189				continue;
13190			}
13191	
13192			value = isSet ?
13193				fn( value, that[i], i, that ) :
13194				that[i];
13195	
13196			isSet = true;
13197			i += inc;
13198		}
13199	
13200		return value;
13201	}
13202	
13203	/**
13204	 * Add a column to the list used for the table with default values
13205	 *  @param {object} oSettings dataTables settings object
13206	 *  @param {node} nTh The th element for this column
13207	 *  @memberof DataTable#oApi
13208	 */
13209	function _fnAddColumn( oSettings, nTh )
13210	{
13211		// Add column to aoColumns array
13212		var oDefaults = DataTable.defaults.column;
13213		var iCol = oSettings.aoColumns.length;
13214		var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
13215			"nTh": nTh ? nTh : document.createElement('th'),
13216			"sTitle":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',
13217			"aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
13218			"mData": oDefaults.mData ? oDefaults.mData : iCol,
13219			idx: iCol
13220		} );
13221		oSettings.aoColumns.push( oCol );
13222	
13223		// Add search object for column specific search. Note that the `searchCols[ iCol ]`
13224		// passed into extend can be undefined. This allows the user to give a default
13225		// with only some of the parameters defined, and also not give a default
13226		var searchCols = oSettings.aoPreSearchCols;
13227		searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
13228	
13229		// Use the default column options function to initialise classes etc
13230		_fnColumnOptions( oSettings, iCol, $(nTh).data() );
13231	}
13232	
13233	
13234	/**
13235	 * Apply options for a column
13236	 *  @param {object} oSettings dataTables settings object
13237	 *  @param {int} iCol column index to consider
13238	 *  @param {object} oOptions object with sType, bVisible and bSearchable etc
13239	 *  @memberof DataTable#oApi
13240	 */
13241	function _fnColumnOptions( oSettings, iCol, oOptions )
13242	{
13243		var oCol = oSettings.aoColumns[ iCol ];
13244		var oClasses = oSettings.oClasses;
13245		var th = $(oCol.nTh);
13246	
13247		// Try to get width information from the DOM. We can't get it from CSS
13248		// as we'd need to parse the CSS stylesheet. `width` option can override
13249		if ( ! oCol.sWidthOrig ) {
13250			// Width attribute
13251			oCol.sWidthOrig = th.attr('width') || null;
13252	
13253			// Style attribute
13254			var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
13255			if ( t ) {
13256				oCol.sWidthOrig = t[1];
13257			}
13258		}
13259	
13260		/* User specified column options */
13261		if ( oOptions !== undefined && oOptions !== null )
13262		{
13263			// Backwards compatibility
13264			_fnCompatCols( oOptions );
13265	
13266			// Map camel case parameters to their Hungarian counterparts
13267			_fnCamelToHungarian( DataTable.defaults.column, oOptions, true );
13268	
13269			/* Backwards compatibility for mDataProp */
13270			if ( oOptions.mDataProp !== undefined && !oOptions.mData )
13271			{
13272				oOptions.mData = oOptions.mDataProp;
13273			}
13274	
13275			if ( oOptions.sType )
13276			{
13277				oCol._sManualType = oOptions.sType;
13278			}
13279	
13280			// `class` is a reserved word in Javascript, so we need to provide
13281			// the ability to use a valid name for the camel case input
13282			if ( oOptions.className && ! oOptions.sClass )
13283			{
13284				oOptions.sClass = oOptions.className;
13285			}
13286			if ( oOptions.sClass ) {
13287				th.addClass( oOptions.sClass );
13288			}
13289	
13290			$.extend( oCol, oOptions );
13291			_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
13292	
13293			/* iDataSort to be applied (backwards compatibility), but aDataSort will take
13294			 * priority if defined
13295			 */
13296			if ( oOptions.iDataSort !== undefined )
13297			{
13298				oCol.aDataSort = [ oOptions.iDataSort ];
13299			}
13300			_fnMap( oCol, oOptions, "aDataSort" );
13301		}
13302	
13303		/* Cache the data get and set functions for speed */
13304		var mDataSrc = oCol.mData;
13305		var mData = _fnGetObjectDataFn( mDataSrc );
13306		var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
13307	
13308		var attrTest = function( src ) {
13309			return typeof src === 'string' && src.indexOf('@') !== -1;
13310		};
13311		oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
13312			attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
13313		);
13314		oCol._setter = null;
13315	
13316		oCol.fnGetData = function (rowData, type, meta) {
13317			var innerData = mData( rowData, type, undefined, meta );
13318	
13319			return mRender && type ?
13320				mRender( innerData, type, rowData, meta ) :
13321				innerData;
13322		};
13323		oCol.fnSetData = function ( rowData, val, meta ) {
13324			return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
13325		};
13326	
13327		// Indicate if DataTables should read DOM data as an object or array
13328		// Used in _fnGetRowElements
13329		if ( typeof mDataSrc !== 'number' ) {
13330			oSettings._rowReadObject = true;
13331		}
13332	
13333		/* Feature sorting overrides column specific when off */
13334		if ( !oSettings.oFeatures.bSort )
13335		{
13336			oCol.bSortable = false;
13337			th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
13338		}
13339	
13340		/* Check that the class assignment is correct for sorting */
13341		var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
13342		var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
13343		if ( !oCol.bSortable || (!bAsc && !bDesc) )
13344		{
13345			oCol.sSortingClass = oClasses.sSortableNone;
13346			oCol.sSortingClassJUI = "";
13347		}
13348		else if ( bAsc && !bDesc )
13349		{
13350			oCol.sSortingClass = oClasses.sSortableAsc;
13351			oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
13352		}
13353		else if ( !bAsc && bDesc )
13354		{
13355			oCol.sSortingClass = oClasses.sSortableDesc;
13356			oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
13357		}
13358		else
13359		{
13360			oCol.sSortingClass = oClasses.sSortable;
13361			oCol.sSortingClassJUI = oClasses.sSortJUI;
13362		}
13363	}
13364	
13365	
13366	/**
13367	 * Adjust the table column widths for new data. Note: you would probably want to
13368	 * do a redraw after calling this function!
13369	 *  @param {object} settings dataTables settings object
13370	 *  @memberof DataTable#oApi
13371	 */
13372	function _fnAdjustColumnSizing ( settings )
13373	{
13374		/* Not interested in doing column width calculation if auto-width is disabled */
13375		if ( settings.oFeatures.bAutoWidth !== false )
13376		{
13377			var columns = settings.aoColumns;
13378	
13379			_fnCalculateColumnWidths( settings );
13380			for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
13381			{
13382				columns[i].nTh.style.width = columns[i].sWidth;
13383			}
13384		}
13385	
13386		var scroll = settings.oScroll;
13387		if ( scroll.sY !== '' || scroll.sX !== '')
13388		{
13389			_fnScrollDraw( settings );
13390		}
13391	
13392		_fnCallbackFire( settings, null, 'column-sizing', [settings] );
13393	}
13394	
13395	
13396	/**
13397	 * Convert the index of a visible column to the index in the data array (take account
13398	 * of hidden columns)
13399	 *  @param {object} oSettings dataTables settings object
13400	 *  @param {int} iMatch Visible column index to lookup
13401	 *  @returns {int} i the data index
13402	 *  @memberof DataTable#oApi
13403	 */
13404	function _fnVisibleToColumnIndex( oSettings, iMatch )
13405	{
13406		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
13407	
13408		return typeof aiVis[iMatch] === 'number' ?
13409			aiVis[iMatch] :
13410			null;
13411	}
13412	
13413	
13414	/**
13415	 * Convert the index of an index in the data array and convert it to the visible
13416	 *   column index (take account of hidden columns)
13417	 *  @param {int} iMatch Column index to lookup
13418	 *  @param {object} oSettings dataTables settings object
13419	 *  @returns {int} i the data index
13420	 *  @memberof DataTable#oApi
13421	 */
13422	function _fnColumnIndexToVisible( oSettings, iMatch )
13423	{
13424		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
13425		var iPos = $.inArray( iMatch, aiVis );
13426	
13427		return iPos !== -1 ? iPos : null;
13428	}
13429	
13430	
13431	/**
13432	 * Get the number of visible columns
13433	 *  @param {object} oSettings dataTables settings object
13434	 *  @returns {int} i the number of visible columns
13435	 *  @memberof DataTable#oApi
13436	 */
13437	function _fnVisbleColumns( oSettings )
13438	{
13439		var vis = 0;
13440	
13441		// No reduce in IE8, use a loop for now
13442		$.each( oSettings.aoColumns, function ( i, col ) {
13443			if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
13444				vis++;
13445			}
13446		} );
13447	
13448		return vis;
13449	}
13450	
13451	
13452	/**
13453	 * Get an array of column indexes that match a given property
13454	 *  @param {object} oSettings dataTables settings object
13455	 *  @param {string} sParam Parameter in aoColumns to look for - typically
13456	 *    bVisible or bSearchable
13457	 *  @returns {array} Array of indexes with matched properties
13458	 *  @memberof DataTable#oApi
13459	 */
13460	function _fnGetColumns( oSettings, sParam )
13461	{
13462		var a = [];
13463	
13464		$.map( oSettings.aoColumns, function(val, i) {
13465			if ( val[sParam] ) {
13466				a.push( i );
13467			}
13468		} );
13469	
13470		return a;
13471	}
13472	
13473	
13474	/**
13475	 * Calculate the 'type' of a column
13476	 *  @param {object} settings dataTables settings object
13477	 *  @memberof DataTable#oApi
13478	 */
13479	function _fnColumnTypes ( settings )
13480	{
13481		var columns = settings.aoColumns;
13482		var data = settings.aoData;
13483		var types = DataTable.ext.type.detect;
13484		var i, ien, j, jen, k, ken;
13485		var col, cell, detectedType, cache;
13486	
13487		// For each column, spin over the 
13488		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
13489			col = columns[i];
13490			cache = [];
13491	
13492			if ( ! col.sType && col._sManualType ) {
13493				col.sType = col._sManualType;
13494			}
13495			else if ( ! col.sType ) {
13496				for ( j=0, jen=types.length ; j<jen ; j++ ) {
13497					for ( k=0, ken=data.length ; k<ken ; k++ ) {
13498						// Use a cache array so we only need to get the type data
13499						// from the formatter once (when using multiple detectors)
13500						if ( cache[k] === undefined ) {
13501							cache[k] = _fnGetCellData( settings, k, i, 'type' );
13502						}
13503	
13504						detectedType = types[j]( cache[k], settings );
13505	
13506						// If null, then this type can't apply to this column, so
13507						// rather than testing all cells, break out. There is an
13508						// exception for the last type which is `html`. We need to
13509						// scan all rows since it is possible to mix string and HTML
13510						// types
13511						if ( ! detectedType && j !== types.length-1 ) {
13512							break;
13513						}
13514	
13515						// Only a single match is needed for html type since it is
13516						// bottom of the pile and very similar to string - but it
13517						// must not be empty
13518						if ( detectedType === 'html' && ! _empty(cache[k]) ) {
13519							break;
13520						}
13521					}
13522	
13523					// Type is valid for all data points in the column - use this
13524					// type
13525					if ( detectedType ) {
13526						col.sType = detectedType;
13527						break;
13528					}
13529				}
13530	
13531				// Fall back - if no type was detected, always use string
13532				if ( ! col.sType ) {
13533					col.sType = 'string';
13534				}
13535			}
13536		}
13537	}
13538	
13539	
13540	/**
13541	 * Take the column definitions and static columns arrays and calculate how
13542	 * they relate to column indexes. The callback function will then apply the
13543	 * definition found for a column to a suitable configuration object.
13544	 *  @param {object} oSettings dataTables settings object
13545	 *  @param {array} aoColDefs The aoColumnDefs array that is to be applied
13546	 *  @param {array} aoCols The aoColumns array that defines columns individually
13547	 *  @param {function} fn Callback function - takes two parameters, the calculated
13548	 *    column index and the definition for that column.
13549	 *  @memberof DataTable#oApi
13550	 */
13551	function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
13552	{
13553		var i, iLen, j, jLen, k, kLen, def;
13554		var columns = oSettings.aoColumns;
13555	
13556		// Column definitions with aTargets
13557		if ( aoColDefs )
13558		{
13559			/* Loop over the definitions array - loop in reverse so first instance has priority */
13560			for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
13561			{
13562				def = aoColDefs[i];
13563	
13564				/* Each definition can target multiple columns, as it is an array */
13565				var aTargets = def.targets !== undefined ?
13566					def.targets :
13567					
vendor: 15,848 bytes, lines 13567-14137
13567def.aTargets;
13568	
13569				if ( ! Array.isArray( aTargets ) )
13570				{
13571					aTargets = [ aTargets ];
13572				}
13573	
13574				for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
13575				{
13576					if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
13577					{
13578						/* Add columns that we don't yet know about */
13579						while( columns.length <= aTargets[j] )
13580						{
13581							_fnAddColumn( oSettings );
13582						}
13583	
13584						/* Integer, basic index */
13585						fn( aTargets[j], def );
13586					}
13587					else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
13588					{
13589						/* Negative integer, right to left column counting */
13590						fn( columns.length+aTargets[j], def );
13591					}
13592					else if ( typeof aTargets[j] === 'string' )
13593					{
13594						/* Class name matching on TH element */
13595						for ( k=0, kLen=columns.length ; k<kLen ; k++ )
13596						{
13597							if ( aTargets[j] == "_all" ||
13598							     $(columns[k].nTh).hasClass( aTargets[j] ) )
13599							{
13600								fn( k, def );
13601							}
13602						}
13603					}
13604				}
13605			}
13606		}
13607	
13608		// Statically defined columns array
13609		if ( aoCols )
13610		{
13611			for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
13612			{
13613				fn( i, aoCols[i] );
13614			}
13615		}
13616	}
13617	
13618	/**
13619	 * Add a data array to the table, creating DOM node etc. This is the parallel to
13620	 * _fnGatherData, but for adding rows from a Javascript source, rather than a
13621	 * DOM source.
13622	 *  @param {object} oSettings dataTables settings object
13623	 *  @param {array} aData data array to be added
13624	 *  @param {node} [nTr] TR element to add to the table - optional. If not given,
13625	 *    DataTables will create a row automatically
13626	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
13627	 *    if nTr is.
13628	 *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
13629	 *  @memberof DataTable#oApi
13630	 */
13631	function _fnAddData ( oSettings, aDataIn, nTr, anTds )
13632	{
13633		/* Create the object for storing information about this new row */
13634		var iRow = oSettings.aoData.length;
13635		var oData = $.extend( true, {}, DataTable.models.oRow, {
13636			src: nTr ? 'dom' : 'data',
13637			idx: iRow
13638		} );
13639	
13640		oData._aData = aDataIn;
13641		oSettings.aoData.push( oData );
13642	
13643		/* Create the cells */
13644		var nTd, sThisType;
13645		var columns = oSettings.aoColumns;
13646	
13647		// Invalidate the column types as the new data needs to be revalidated
13648		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
13649		{
13650			columns[i].sType = null;
13651		}
13652	
13653		/* Add to the display array */
13654		oSettings.aiDisplayMaster.push( iRow );
13655	
13656		var id = oSettings.rowIdFn( aDataIn );
13657		if ( id !== undefined ) {
13658			oSettings.aIds[ id ] = oData;
13659		}
13660	
13661		/* Create the DOM information, or register it if already present */
13662		if ( nTr || ! oSettings.oFeatures.bDeferRender )
13663		{
13664			_fnCreateTr( oSettings, iRow, nTr, anTds );
13665		}
13666	
13667		return iRow;
13668	}
13669	
13670	
13671	/**
13672	 * Add one or more TR elements to the table. Generally we'd expect to
13673	 * use this for reading data from a DOM sourced table, but it could be
13674	 * used for an TR element. Note that if a TR is given, it is used (i.e.
13675	 * it is not cloned).
13676	 *  @param {object} settings dataTables settings object
13677	 *  @param {array|node|jQuery} trs The TR element(s) to add to the table
13678	 *  @returns {array} Array of indexes for the added rows
13679	 *  @memberof DataTable#oApi
13680	 */
13681	function _fnAddTr( settings, trs )
13682	{
13683		var row;
13684	
13685		// Allow an individual node to be passed in
13686		if ( ! (trs instanceof $) ) {
13687			trs = $(trs);
13688		}
13689	
13690		return trs.map( function (i, el) {
13691			row = _fnGetRowElements( settings, el );
13692			return _fnAddData( settings, row.data, el, row.cells );
13693		} );
13694	}
13695	
13696	
13697	/**
13698	 * Take a TR element and convert it to an index in aoData
13699	 *  @param {object} oSettings dataTables settings object
13700	 *  @param {node} n the TR element to find
13701	 *  @returns {int} index if the node is found, null if not
13702	 *  @memberof DataTable#oApi
13703	 */
13704	function _fnNodeToDataIndex( oSettings, n )
13705	{
13706		return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
13707	}
13708	
13709	
13710	/**
13711	 * Take a TD element and convert it into a column data index (not the visible index)
13712	 *  @param {object} oSettings dataTables settings object
13713	 *  @param {int} iRow The row number the TD/TH can be found in
13714	 *  @param {node} n The TD/TH element to find
13715	 *  @returns {int} index if the node is found, -1 if not
13716	 *  @memberof DataTable#oApi
13717	 */
13718	function _fnNodeToColumnIndex( oSettings, iRow, n )
13719	{
13720		return $.inArray( n, oSettings.aoData[ iRow ].anCells );
13721	}
13722	
13723	
13724	/**
13725	 * Get the data for a given cell from the internal cache, taking into account data mapping
13726	 *  @param {object} settings dataTables settings object
13727	 *  @param {int} rowIdx aoData row id
13728	 *  @param {int} colIdx Column index
13729	 *  @param {string} type data get type ('display', 'type' 'filter|search' 'sort|order')
13730	 *  @returns {*} Cell data
13731	 *  @memberof DataTable#oApi
13732	 */
13733	function _fnGetCellData( settings, rowIdx, colIdx, type )
13734	{
13735		if (type === 'search') {
13736			type = 'filter';
13737		}
13738		else if (type === 'order') {
13739			type = 'sort';
13740		}
13741	
13742		var draw           = settings.iDraw;
13743		var col            = settings.aoColumns[colIdx];
13744		var rowData        = settings.aoData[rowIdx]._aData;
13745		var defaultContent = col.sDefaultContent;
13746		var cellData       = col.fnGetData( rowData, type, {
13747			settings: settings,
13748			row:      rowIdx,
13749			col:      colIdx
13750		} );
13751	
13752		if ( cellData === undefined ) {
13753			if ( settings.iDrawError != draw && defaultContent === null ) {
13754				_fnLog( settings, 0, "Requested unknown parameter "+
13755					(typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
13756					" for row "+rowIdx+", column "+colIdx, 4 );
13757				settings.iDrawError = draw;
13758			}
13759			return defaultContent;
13760		}
13761	
13762		// When the data source is null and a specific data type is requested (i.e.
13763		// not the original data), we can use default column data
13764		if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
13765			cellData = defaultContent;
13766		}
13767		else if ( typeof cellData === 'function' ) {
13768			// If the data source is a function, then we run it and use the return,
13769			// executing in the scope of the data object (for instances)
13770			return cellData.call( rowData );
13771		}
13772	
13773		if ( cellData === null && type === 'display' ) {
13774			return '';
13775		}
13776	
13777		if ( type === 'filter' ) {
13778			var fomatters = DataTable.ext.type.search;
13779	
13780			if ( fomatters[ col.sType ] ) {
13781				cellData = fomatters[ col.sType ]( cellData );
13782			}
13783		}
13784	
13785		return cellData;
13786	}
13787	
13788	
13789	/**
13790	 * Set the value for a specific cell, into the internal data cache
13791	 *  @param {object} settings dataTables settings object
13792	 *  @param {int} rowIdx aoData row id
13793	 *  @param {int} colIdx Column index
13794	 *  @param {*} val Value to set
13795	 *  @memberof DataTable#oApi
13796	 */
13797	function _fnSetCellData( settings, rowIdx, colIdx, val )
13798	{
13799		var col     = settings.aoColumns[colIdx];
13800		var rowData = settings.aoData[rowIdx]._aData;
13801	
13802		col.fnSetData( rowData, val, {
13803			settings: settings,
13804			row:      rowIdx,
13805			col:      colIdx
13806		}  );
13807	}
13808	
13809	
13810	// Private variable that is used to match action syntax in the data property object
13811	var __reArray = /\[.*?\]$/;
13812	var __reFn = /\(\)$/;
13813	
13814	/**
13815	 * Split string on periods, taking into account escaped periods
13816	 * @param  {string} str String to split
13817	 * @return {array} Split string
13818	 */
13819	function _fnSplitObjNotation( str )
13820	{
13821		return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
13822			return s.replace(/\\\./g, '.');
13823		} );
13824	}
13825	
13826	
13827	/**
13828	 * Return a function that can be used to get data from a source object, taking
13829	 * into account the ability to use nested objects as a source
13830	 *  @param {string|int|function} mSource The data source for the object
13831	 *  @returns {function} Data get function
13832	 *  @memberof DataTable#oApi
13833	 */
13834	var _fnGetObjectDataFn = DataTable.util.get;
13835	
13836	
13837	/**
13838	 * Return a function that can be used to set data from a source object, taking
13839	 * into account the ability to use nested objects as a source
13840	 *  @param {string|int|function} mSource The data source for the object
13841	 *  @returns {function} Data set function
13842	 *  @memberof DataTable#oApi
13843	 */
13844	var _fnSetObjectDataFn = DataTable.util.set;
13845	
13846	
13847	/**
13848	 * Return an array with the full table data
13849	 *  @param {object} oSettings dataTables settings object
13850	 *  @returns array {array} aData Master data array
13851	 *  @memberof DataTable#oApi
13852	 */
13853	function _fnGetDataMaster ( settings )
13854	{
13855		return _pluck( settings.aoData, '_aData' );
13856	}
13857	
13858	
13859	/**
13860	 * Nuke the table
13861	 *  @param {object} oSettings dataTables settings object
13862	 *  @memberof DataTable#oApi
13863	 */
13864	function _fnClearTable( settings )
13865	{
13866		settings.aoData.length = 0;
13867		settings.aiDisplayMaster.length = 0;
13868		settings.aiDisplay.length = 0;
13869		settings.aIds = {};
13870	}
13871	
13872	
13873	 /**
13874	 * Take an array of integers (index array) and remove a target integer (value - not
13875	 * the key!)
13876	 *  @param {array} a Index array to target
13877	 *  @param {int} iTarget value to find
13878	 *  @memberof DataTable#oApi
13879	 */
13880	function _fnDeleteIndex( a, iTarget, splice )
13881	{
13882		var iTargetIndex = -1;
13883	
13884		for ( var i=0, iLen=a.length ; i<iLen ; i++ )
13885		{
13886			if ( a[i] == iTarget )
13887			{
13888				iTargetIndex = i;
13889			}
13890			else if ( a[i] > iTarget )
13891			{
13892				a[i]--;
13893			}
13894		}
13895	
13896		if ( iTargetIndex != -1 && splice === undefined )
13897		{
13898			a.splice( iTargetIndex, 1 );
13899		}
13900	}
13901	
13902	
13903	/**
13904	 * Mark cached data as invalid such that a re-read of the data will occur when
13905	 * the cached data is next requested. Also update from the data source object.
13906	 *
13907	 * @param {object} settings DataTables settings object
13908	 * @param {int}    rowIdx   Row index to invalidate
13909	 * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'
13910	 *     or 'data'
13911	 * @param {int}    [colIdx] Column index to invalidate. If undefined the whole
13912	 *     row will be invalidated
13913	 * @memberof DataTable#oApi
13914	 *
13915	 * @todo For the modularisation of v1.11 this will need to become a callback, so
13916	 *   the sort and filter methods can subscribe to it. That will required
13917	 *   initialisation options for sorting, which is why it is not already baked in
13918	 */
13919	function _fnInvalidate( settings, rowIdx, src, colIdx )
13920	{
13921		var row = settings.aoData[ rowIdx ];
13922		var i, ien;
13923		var cellWrite = function ( cell, col ) {
13924			// This is very frustrating, but in IE if you just write directly
13925			// to innerHTML, and elements that are overwritten are GC'ed,
13926			// even if there is a reference to them elsewhere
13927			while ( cell.childNodes.length ) {
13928				cell.removeChild( cell.firstChild );
13929			}
13930	
13931			cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
13932		};
13933	
13934		// Are we reading last data from DOM or the data object?
13935		if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
13936			// Read the data from the DOM
13937			row._aData = _fnGetRowElements(
13938					settings, row, colIdx, colIdx === undefined ? undefined : row._aData
13939				)
13940				.data;
13941		}
13942		else {
13943			// Reading from data object, update the DOM
13944			var cells = row.anCells;
13945	
13946			if ( cells ) {
13947				if ( colIdx !== undefined ) {
13948					cellWrite( cells[colIdx], colIdx );
13949				}
13950				else {
13951					for ( i=0, ien=cells.length ; i<ien ; i++ ) {
13952						cellWrite( cells[i], i );
13953					}
13954				}
13955			}
13956		}
13957	
13958		// For both row and cell invalidation, the cached data for sorting and
13959		// filtering is nulled out
13960		row._aSortData = null;
13961		row._aFilterData = null;
13962	
13963		// Invalidate the type for a specific column (if given) or all columns since
13964		// the data might have changed
13965		var cols = settings.aoColumns;
13966		if ( colIdx !== undefined ) {
13967			cols[ colIdx ].sType = null;
13968		}
13969		else {
13970			for ( i=0, ien=cols.length ; i<ien ; i++ ) {
13971				cols[i].sType = null;
13972			}
13973	
13974			// Update DataTables special `DT_*` attributes for the row
13975			_fnRowAttributes( settings, row );
13976		}
13977	}
13978	
13979	
13980	/**
13981	 * Build a data source object from an HTML row, reading the contents of the
13982	 * cells that are in the row.
13983	 *
13984	 * @param {object} settings DataTables settings object
13985	 * @param {node|object} TR element from which to read data or existing row
13986	 *   object from which to re-read the data from the cells
13987	 * @param {int} [colIdx] Optional column index
13988	 * @param {array|object} [d] Data source object. If `colIdx` is given then this
13989	 *   parameter should also be given and will be used to write the data into.
13990	 *   Only the column in question will be written
13991	 * @returns {object} Object with two parameters: `data` the data read, in
13992	 *   document order, and `cells` and array of nodes (they can be useful to the
13993	 *   caller, so rather than needing a second traversal to get them, just return
13994	 *   them from here).
13995	 * @memberof DataTable#oApi
13996	 */
13997	function _fnGetRowElements( settings, row, colIdx, d )
13998	{
13999		var
14000			tds = [],
14001			td = row.firstChild,
14002			name, col, o, i=0, contents,
14003			columns = settings.aoColumns,
14004			objectRead = settings._rowReadObject;
14005	
14006		// Allow the data object to be passed in, or construct
14007		d = d !== undefined ?
14008			d :
14009			objectRead ?
14010				{} :
14011				[];
14012	
14013		var attr = function ( str, td  ) {
14014			if ( typeof str === 'string' ) {
14015				var idx = str.indexOf('@');
14016	
14017				if ( idx !== -1 ) {
14018					var attr = str.substring( idx+1 );
14019					var setter = _fnSetObjectDataFn( str );
14020					setter( d, td.getAttribute( attr ) );
14021				}
14022			}
14023		};
14024	
14025		// Read data from a cell and store into the data object
14026		var cellProcess = function ( cell ) {
14027			if ( colIdx === undefined || colIdx === i ) {
14028				col = columns[i];
14029				contents = (cell.innerHTML).trim();
14030	
14031				if ( col && col._bAttrSrc ) {
14032					var setter = _fnSetObjectDataFn( col.mData._ );
14033					setter( d, contents );
14034	
14035					attr( col.mData.sort, cell );
14036					attr( col.mData.type, cell );
14037					attr( col.mData.filter, cell );
14038				}
14039				else {
14040					// Depending on the `data` option for the columns the data can
14041					// be read to either an object or an array.
14042					if ( objectRead ) {
14043						if ( ! col._setter ) {
14044							// Cache the setter function
14045							col._setter = _fnSetObjectDataFn( col.mData );
14046						}
14047						col._setter( d, contents );
14048					}
14049					else {
14050						d[i] = contents;
14051					}
14052				}
14053			}
14054	
14055			i++;
14056		};
14057	
14058		if ( td ) {
14059			// `tr` element was passed in
14060			while ( td ) {
14061				name = td.nodeName.toUpperCase();
14062	
14063				if ( name == "TD" || name == "TH" ) {
14064					cellProcess( td );
14065					tds.push( td );
14066				}
14067	
14068				td = td.nextSibling;
14069			}
14070		}
14071		else {
14072			// Existing row object passed in
14073			tds = row.anCells;
14074	
14075			for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
14076				cellProcess( tds[j] );
14077			}
14078		}
14079	
14080		// Read the ID from the DOM if present
14081		var rowNode = row.firstChild ? row : row.nTr;
14082	
14083		if ( rowNode ) {
14084			var id = rowNode.getAttribute( 'id' );
14085	
14086			if ( id ) {
14087				_fnSetObjectDataFn( settings.rowId )( d, id );
14088			}
14089		}
14090	
14091		return {
14092			data: d,
14093			cells: tds
14094		};
14095	}
14096	/**
14097	 * Create a new TR element (and it's TD children) for a row
14098	 *  @param {object} oSettings dataTables settings object
14099	 *  @param {int} iRow Row to consider
14100	 *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,
14101	 *    DataTables will create a row automatically
14102	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
14103	 *    if nTr is.
14104	 *  @memberof DataTable#oApi
14105	 */
14106	function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
14107	{
14108		var
14109			row = oSettings.aoData[iRow],
14110			rowData = row._aData,
14111			cells = [],
14112			nTr, nTd, oCol,
14113			i, iLen, create;
14114	
14115		if ( row.nTr === null )
14116		{
14117			nTr = nTrIn || document.createElement('tr');
14118	
14119			row.nTr = nTr;
14120			row.anCells = cells;
14121	
14122			/* Use a private property on the node to allow reserve mapping from the node
14123			 * to the aoData array for fast look up
14124			 */
14125			nTr._DT_RowIndex = iRow;
14126	
14127			/* Special parameters can be given by the data source to be used on the row */
14128			_fnRowAttributes( oSettings, row );
14129	
14130			/* Process each column */
14131			for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
14132			{
14133				oCol = oSettings.aoColumns[i];
14134				create = nTrIn ? false : true;
14135	
14136				nTd = create ? document.createElement( oCol.sCellType ) : anTds[i];
14137	
vendor: 8,418 bytes, lines 14137-14445
14137			nTd._DT_CellIndex = {
14138					row: iRow,
14139					column: i
14140				};
14141				
14142				cells.push( nTd );
14143	
14144				// Need to create the HTML if new, or if a rendering function is defined
14145				if ( create || ((oCol.mRender || oCol.mData !== i) &&
14146					 (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
14147				)) {
14148					nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
14149				}
14150	
14151				/* Add user defined class */
14152				if ( oCol.sClass )
14153				{
14154					nTd.className += ' '+oCol.sClass;
14155				}
14156	
14157				// Visibility - add or remove as required
14158				if ( oCol.bVisible && ! nTrIn )
14159				{
14160					nTr.appendChild( nTd );
14161				}
14162				else if ( ! oCol.bVisible && nTrIn )
14163				{
14164					nTd.parentNode.removeChild( nTd );
14165				}
14166	
14167				if ( oCol.fnCreatedCell )
14168				{
14169					oCol.fnCreatedCell.call( oSettings.oInstance,
14170						nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
14171					);
14172				}
14173			}
14174	
14175			_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] );
14176		}
14177	}
14178	
14179	
14180	/**
14181	 * Add attributes to a row based on the special `DT_*` parameters in a data
14182	 * source object.
14183	 *  @param {object} settings DataTables settings object
14184	 *  @param {object} DataTables row object for the row to be modified
14185	 *  @memberof DataTable#oApi
14186	 */
14187	function _fnRowAttributes( settings, row )
14188	{
14189		var tr = row.nTr;
14190		var data = row._aData;
14191	
14192		if ( tr ) {
14193			var id = settings.rowIdFn( data );
14194	
14195			if ( id ) {
14196				tr.id = id;
14197			}
14198	
14199			if ( data.DT_RowClass ) {
14200				// Remove any classes added by DT_RowClass before
14201				var a = data.DT_RowClass.split(' ');
14202				row.__rowc = row.__rowc ?
14203					_unique( row.__rowc.concat( a ) ) :
14204					a;
14205	
14206				$(tr)
14207					.removeClass( row.__rowc.join(' ') )
14208					.addClass( data.DT_RowClass );
14209			}
14210	
14211			if ( data.DT_RowAttr ) {
14212				$(tr).attr( data.DT_RowAttr );
14213			}
14214	
14215			if ( data.DT_RowData ) {
14216				$(tr).data( data.DT_RowData );
14217			}
14218		}
14219	}
14220	
14221	
14222	/**
14223	 * Create the HTML header for the table
14224	 *  @param {object} oSettings dataTables settings object
14225	 *  @memberof DataTable#oApi
14226	 */
14227	function _fnBuildHead( oSettings )
14228	{
14229		var i, ien, cell, row, column;
14230		var thead = oSettings.nTHead;
14231		var tfoot = oSettings.nTFoot;
14232		var createHeader = $('th, td', thead).length === 0;
14233		var classes = oSettings.oClasses;
14234		var columns = oSettings.aoColumns;
14235	
14236		if ( createHeader ) {
14237			row = $('<tr/>').appendTo( thead );
14238		}
14239	
14240		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
14241			column = columns[i];
14242			cell = $( column.nTh ).addClass( column.sClass );
14243	
14244			if ( createHeader ) {
14245				cell.appendTo( row );
14246			}
14247	
14248			// 1.11 move into sorting
14249			if ( oSettings.oFeatures.bSort ) {
14250				cell.addClass( column.sSortingClass );
14251	
14252				if ( column.bSortable !== false ) {
14253					cell
14254						.attr( 'tabindex', oSettings.iTabIndex )
14255						.attr( 'aria-controls', oSettings.sTableId );
14256	
14257					_fnSortAttachListener( oSettings, column.nTh, i );
14258				}
14259			}
14260	
14261			if ( column.sTitle != cell[0].innerHTML ) {
14262				cell.html( column.sTitle );
14263			}
14264	
14265			_fnRenderer( oSettings, 'header' )(
14266				oSettings, cell, column, classes
14267			);
14268		}
14269	
14270		if ( createHeader ) {
14271			_fnDetectHeader( oSettings.aoHeader, thead );
14272		}
14273	
14274		/* Deal with the footer - add classes if required */
14275		$(thead).children('tr').children('th, td').addClass( classes.sHeaderTH );
14276		$(tfoot).children('tr').children('th, td').addClass( classes.sFooterTH );
14277	
14278		// Cache the footer cells. Note that we only take the cells from the first
14279		// row in the footer. If there is more than one row the user wants to
14280		// interact with, they need to use the table().foot() method. Note also this
14281		// allows cells to be used for multiple columns using colspan
14282		if ( tfoot !== null ) {
14283			var cells = oSettings.aoFooter[0];
14284	
14285			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
14286				column = columns[i];
14287				column.nTf = cells[i].cell;
14288	
14289				if ( column.sClass ) {
14290					$(column.nTf).addClass( column.sClass );
14291				}
14292			}
14293		}
14294	}
14295	
14296	
14297	/**
14298	 * Draw the header (or footer) element based on the column visibility states. The
14299	 * methodology here is to use the layout array from _fnDetectHeader, modified for
14300	 * the instantaneous column visibility, to construct the new layout. The grid is
14301	 * traversed over cell at a time in a rows x columns grid fashion, although each
14302	 * cell insert can cover multiple elements in the grid - which is tracks using the
14303	 * aApplied array. Cell inserts in the grid will only occur where there isn't
14304	 * already a cell in that position.
14305	 *  @param {object} oSettings dataTables settings object
14306	 *  @param array {objects} aoSource Layout array from _fnDetectHeader
14307	 *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
14308	 *  @memberof DataTable#oApi
14309	 */
14310	function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
14311	{
14312		var i, iLen, j, jLen, k, kLen, n, nLocalTr;
14313		var aoLocal = [];
14314		var aApplied = [];
14315		var iColumns = oSettings.aoColumns.length;
14316		var iRowspan, iColspan;
14317	
14318		if ( ! aoSource )
14319		{
14320			return;
14321		}
14322	
14323		if (  bIncludeHidden === undefined )
14324		{
14325			bIncludeHidden = false;
14326		}
14327	
14328		/* Make a copy of the master layout array, but without the visible columns in it */
14329		for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
14330		{
14331			aoLocal[i] = aoSource[i].slice();
14332			aoLocal[i].nTr = aoSource[i].nTr;
14333	
14334			/* Remove any columns which are currently hidden */
14335			for ( j=iColumns-1 ; j>=0 ; j-- )
14336			{
14337				if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
14338				{
14339					aoLocal[i].splice( j, 1 );
14340				}
14341			}
14342	
14343			/* Prep the applied array - it needs an element for each row */
14344			aApplied.push( [] );
14345		}
14346	
14347		for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
14348		{
14349			nLocalTr = aoLocal[i].nTr;
14350	
14351			/* All cells are going to be replaced, so empty out the row */
14352			if ( nLocalTr )
14353			{
14354				while( (n = nLocalTr.firstChild) )
14355				{
14356					nLocalTr.removeChild( n );
14357				}
14358			}
14359	
14360			for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
14361			{
14362				iRowspan = 1;
14363				iColspan = 1;
14364	
14365				/* Check to see if there is already a cell (row/colspan) covering our target
14366				 * insert point. If there is, then there is nothing to do.
14367				 */
14368				if ( aApplied[i][j] === undefined )
14369				{
14370					nLocalTr.appendChild( aoLocal[i][j].cell );
14371					aApplied[i][j] = 1;
14372	
14373					/* Expand the cell to cover as many rows as needed */
14374					while ( aoLocal[i+iRowspan] !== undefined &&
14375					        aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
14376					{
14377						aApplied[i+iRowspan][j] = 1;
14378						iRowspan++;
14379					}
14380	
14381					/* Expand the cell to cover as many columns as needed */
14382					while ( aoLocal[i][j+iColspan] !== undefined &&
14383					        aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
14384					{
14385						/* Must update the applied array over the rows for the columns */
14386						for ( k=0 ; k<iRowspan ; k++ )
14387						{
14388							aApplied[i+k][j+iColspan] = 1;
14389						}
14390						iColspan++;
14391					}
14392	
14393					/* Do the actual expansion in the DOM */
14394					$(aoLocal[i][j].cell)
14395						.attr('rowspan', iRowspan)
14396						.attr('colspan', iColspan);
14397				}
14398			}
14399		}
14400	}
14401	
14402	
14403	/**
14404	 * Insert the required TR nodes into the table for display
14405	 *  @param {object} oSettings dataTables settings object
14406	 *  @param ajaxComplete true after ajax call to complete rendering
14407	 *  @memberof DataTable#oApi
14408	 */
14409	function _fnDraw( oSettings, ajaxComplete )
14410	{
14411		/* Provide a pre-callback function which can be used to cancel the draw is false is returned */
14412		var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
14413		if ( $.inArray( false, aPreDraw ) !== -1 )
14414		{
14415			_fnProcessingDisplay( oSettings, false );
14416			return;
14417		}
14418	
14419		var i, iLen, n;
14420		var anRows = [];
14421		var iRowCount = 0;
14422		var asStripeClasses = oSettings.asStripeClasses;
14423		var iStripes = asStripeClasses.length;
14424		var iOpenRows = oSettings.aoOpenRows.length;
14425		var oLang = oSettings.oLanguage;
14426		var iInitDisplayStart = oSettings.iInitDisplayStart;
14427		var bServerSide = _fnDataSource( oSettings ) == 'ssp';
14428		var aiDisplay = oSettings.aiDisplay;
14429	
14430		oSettings.bDrawing = true;
14431	
14432		/* Check and see if we have an initial draw position from state saving */
14433		if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
14434		{
14435			oSettings._iDisplayStart = bServerSide ?
14436				iInitDisplayStart :
14437				iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
14438					0 :
14439					iInitDisplayStart;
14440	
14441			oSettings.iInitDisplayStart = -1;
14442		}
14443	
14444		var iDisplayStart = oSettings._iDisplayStart;
14445		var iDisplayEnd = oSettings.fnDisplayEnd()
vendor: 10,841 bytes, lines 14445-14849
14445;
14446	
14447		/* Server-side processing draw intercept */
14448		if ( oSettings.bDeferLoading )
14449		{
14450			oSettings.bDeferLoading = false;
14451			oSettings.iDraw++;
14452			_fnProcessingDisplay( oSettings, false );
14453		}
14454		else if ( !bServerSide )
14455		{
14456			oSettings.iDraw++;
14457		}
14458		else if ( !oSettings.bDestroying && !ajaxComplete)
14459		{
14460			_fnAjaxUpdate( oSettings );
14461			return;
14462		}
14463	
14464		if ( aiDisplay.length !== 0 )
14465		{
14466			var iStart = bServerSide ? 0 : iDisplayStart;
14467			var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
14468	
14469			for ( var j=iStart ; j<iEnd ; j++ )
14470			{
14471				var iDataIndex = aiDisplay[j];
14472				var aoData = oSettings.aoData[ iDataIndex ];
14473				if ( aoData.nTr === null )
14474				{
14475					_fnCreateTr( oSettings, iDataIndex );
14476				}
14477	
14478				var nRow = aoData.nTr;
14479	
14480				/* Remove the old striping classes and then add the new one */
14481				if ( iStripes !== 0 )
14482				{
14483					var sStripe = asStripeClasses[ iRowCount % iStripes ];
14484					if ( aoData._sRowStripe != sStripe )
14485					{
14486						$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
14487						aoData._sRowStripe = sStripe;
14488					}
14489				}
14490	
14491				// Row callback functions - might want to manipulate the row
14492				// iRowCount and j are not currently documented. Are they at all
14493				// useful?
14494				_fnCallbackFire( oSettings, 'aoRowCallback', null,
14495					[nRow, aoData._aData, iRowCount, j, iDataIndex] );
14496	
14497				anRows.push( nRow );
14498				iRowCount++;
14499			}
14500		}
14501		else
14502		{
14503			/* Table is empty - create a row with an empty message in it */
14504			var sZero = oLang.sZeroRecords;
14505			if ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )
14506			{
14507				sZero = oLang.sLoadingRecords;
14508			}
14509			else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
14510			{
14511				sZero = oLang.sEmptyTable;
14512			}
14513	
14514			anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
14515				.append( $('<td />', {
14516					'valign':  'top',
14517					'colSpan': _fnVisbleColumns( oSettings ),
14518					'class':   oSettings.oClasses.sRowEmpty
14519				} ).html( sZero ) )[0];
14520		}
14521	
14522		/* Header and footer callbacks */
14523		_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
14524			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
14525	
14526		_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
14527			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
14528	
14529		var body = $(oSettings.nTBody);
14530	
14531		body.children().detach();
14532		body.append( $(anRows) );
14533	
14534		/* Call all required callback functions for the end of a draw */
14535		_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
14536	
14537		/* Draw is complete, sorting and filtering must be as well */
14538		oSettings.bSorted = false;
14539		oSettings.bFiltered = false;
14540		oSettings.bDrawing = false;
14541	}
14542	
14543	
14544	/**
14545	 * Redraw the table - taking account of the various features which are enabled
14546	 *  @param {object} oSettings dataTables settings object
14547	 *  @param {boolean} [holdPosition] Keep the current paging position. By default
14548	 *    the paging is reset to the first page
14549	 *  @memberof DataTable#oApi
14550	 */
14551	function _fnReDraw( settings, holdPosition )
14552	{
14553		var
14554			features = settings.oFeatures,
14555			sort     = features.bSort,
14556			filter   = features.bFilter;
14557	
14558		if ( sort ) {
14559			_fnSort( settings );
14560		}
14561	
14562		if ( filter ) {
14563			_fnFilterComplete( settings, settings.oPreviousSearch );
14564		}
14565		else {
14566			// No filtering, so we want to just use the display master
14567			settings.aiDisplay = settings.aiDisplayMaster.slice();
14568		}
14569	
14570		if ( holdPosition !== true ) {
14571			settings._iDisplayStart = 0;
14572		}
14573	
14574		// Let any modules know about the draw hold position state (used by
14575		// scrolling internally)
14576		settings._drawHold = holdPosition;
14577	
14578		_fnDraw( settings );
14579	
14580		settings._drawHold = false;
14581	}
14582	
14583	
14584	/**
14585	 * Add the options to the page HTML for the table
14586	 *  @param {object} oSettings dataTables settings object
14587	 *  @memberof DataTable#oApi
14588	 */
14589	function _fnAddOptionsHtml ( oSettings )
14590	{
14591		var classes = oSettings.oClasses;
14592		var table = $(oSettings.nTable);
14593		var holding = $('<div/>').insertBefore( table ); // Holding element for speed
14594		var features = oSettings.oFeatures;
14595	
14596		// All DataTables are wrapped in a div
14597		var insert = $('<div/>', {
14598			id:      oSettings.sTableId+'_wrapper',
14599			'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
14600		} );
14601	
14602		oSettings.nHolding = holding[0];
14603		oSettings.nTableWrapper = insert[0];
14604		oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
14605	
14606		/* Loop over the user set positioning and place the elements as needed */
14607		var aDom = oSettings.sDom.split('');
14608		var featureNode, cOption, nNewNode, cNext, sAttr, j;
14609		for ( var i=0 ; i<aDom.length ; i++ )
14610		{
14611			featureNode = null;
14612			cOption = aDom[i];
14613	
14614			if ( cOption == '<' )
14615			{
14616				/* New container div */
14617				nNewNode = $('<div/>')[0];
14618	
14619				/* Check to see if we should append an id and/or a class name to the container */
14620				cNext = aDom[i+1];
14621				if ( cNext == "'" || cNext == '"' )
14622				{
14623					sAttr = "";
14624					j = 2;
14625					while ( aDom[i+j] != cNext )
14626					{
14627						sAttr += aDom[i+j];
14628						j++;
14629					}
14630	
14631					/* Replace jQuery UI constants @todo depreciated */
14632					if ( sAttr == "H" )
14633					{
14634						sAttr = classes.sJUIHeader;
14635					}
14636					else if ( sAttr == "F" )
14637					{
14638						sAttr = classes.sJUIFooter;
14639					}
14640	
14641					/* The attribute can be in the format of "#id.class", "#id" or "class" This logic
14642					 * breaks the string into parts and applies them as needed
14643					 */
14644					if ( sAttr.indexOf('.') != -1 )
14645					{
14646						var aSplit = sAttr.split('.');
14647						nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
14648						nNewNode.className = aSplit[1];
14649					}
14650					else if ( sAttr.charAt(0) == "#" )
14651					{
14652						nNewNode.id = sAttr.substr(1, sAttr.length-1);
14653					}
14654					else
14655					{
14656						nNewNode.className = sAttr;
14657					}
14658	
14659					i += j; /* Move along the position array */
14660				}
14661	
14662				insert.append( nNewNode );
14663				insert = $(nNewNode);
14664			}
14665			else if ( cOption == '>' )
14666			{
14667				/* End container div */
14668				insert = insert.parent();
14669			}
14670			// @todo Move options into their own plugins?
14671			else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
14672			{
14673				/* Length */
14674				featureNode = _fnFeatureHtmlLength( oSettings );
14675			}
14676			else if ( cOption == 'f' && features.bFilter )
14677			{
14678				/* Filter */
14679				featureNode = _fnFeatureHtmlFilter( oSettings );
14680			}
14681			else if ( cOption == 'r' && features.bProcessing )
14682			{
14683				/* pRocessing */
14684				featureNode = _fnFeatureHtmlProcessing( oSettings );
14685			}
14686			else if ( cOption == 't' )
14687			{
14688				/* Table */
14689				featureNode = _fnFeatureHtmlTable( oSettings );
14690			}
14691			else if ( cOption ==  'i' && features.bInfo )
14692			{
14693				/* Info */
14694				featureNode = _fnFeatureHtmlInfo( oSettings );
14695			}
14696			else if ( cOption == 'p' && features.bPaginate )
14697			{
14698				/* Pagination */
14699				featureNode = _fnFeatureHtmlPaginate( oSettings );
14700			}
14701			else if ( DataTable.ext.feature.length !== 0 )
14702			{
14703				/* Plug-in features */
14704				var aoFeatures = DataTable.ext.feature;
14705				for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
14706				{
14707					if ( cOption == aoFeatures[k].cFeature )
14708					{
14709						featureNode = aoFeatures[k].fnInit( oSettings );
14710						break;
14711					}
14712				}
14713			}
14714	
14715			/* Add to the 2D features array */
14716			if ( featureNode )
14717			{
14718				var aanFeatures = oSettings.aanFeatures;
14719	
14720				if ( ! aanFeatures[cOption] )
14721				{
14722					aanFeatures[cOption] = [];
14723				}
14724	
14725				aanFeatures[cOption].push( featureNode );
14726				insert.append( featureNode );
14727			}
14728		}
14729	
14730		/* Built our DOM structure - replace the holding div with what we want */
14731		holding.replaceWith( insert );
14732		oSettings.nHolding = null;
14733	}
14734	
14735	
14736	/**
14737	 * Use the DOM source to create up an array of header cells. The idea here is to
14738	 * create a layout grid (array) of rows x columns, which contains a reference
14739	 * to the cell that that point in the grid (regardless of col/rowspan), such that
14740	 * any column / row could be removed and the new grid constructed
14741	 *  @param array {object} aLayout Array to store the calculated layout in
14742	 *  @param {node} nThead The header/footer element for the table
14743	 *  @memberof DataTable#oApi
14744	 */
14745	function _fnDetectHeader ( aLayout, nThead )
14746	{
14747		var nTrs = $(nThead).children('tr');
14748		var nTr, nCell;
14749		var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
14750		var bUnique;
14751		var fnShiftCol = function ( a, i, j ) {
14752			var k = a[i];
14753	                while ( k[j] ) {
14754				j++;
14755			}
14756			return j;
14757		};
14758	
14759		aLayout.splice( 0, aLayout.length );
14760	
14761		/* We know how many rows there are in the layout - so prep it */
14762		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
14763		{
14764			aLayout.push( [] );
14765		}
14766	
14767		/* Calculate a layout array */
14768		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
14769		{
14770			nTr = nTrs[i];
14771			iColumn = 0;
14772	
14773			/* For every cell in the row... */
14774			nCell = nTr.firstChild;
14775			while ( nCell ) {
14776				if ( nCell.nodeName.toUpperCase() == "TD" ||
14777				     nCell.nodeName.toUpperCase() == "TH" )
14778				{
14779					/* Get the col and rowspan attributes from the DOM and sanitise them */
14780					iColspan = nCell.getAttribute('colspan') * 1;
14781					iRowspan = nCell.getAttribute('rowspan') * 1;
14782					iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
14783					iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
14784	
14785					/* There might be colspan cells already in this row, so shift our target
14786					 * accordingly
14787					 */
14788					iColShifted = fnShiftCol( aLayout, i, iColumn );
14789	
14790					/* Cache calculation for unique columns */
14791					bUnique = iColspan === 1 ? true : false;
14792	
14793					/* If there is col / rowspan, copy the information into the layout grid */
14794					for ( l=0 ; l<iColspan ; l++ )
14795					{
14796						for ( k=0 ; k<iRowspan ; k++ )
14797						{
14798							aLayout[i+k][iColShifted+l] = {
14799								"cell": nCell,
14800								"unique": bUnique
14801							};
14802							aLayout[i+k].nTr = nTr;
14803						}
14804					}
14805				}
14806				nCell = nCell.nextSibling;
14807			}
14808		}
14809	}
14810	
14811	
14812	/**
14813	 * Get an array of unique th elements, one for each column
14814	 *  @param {object} oSettings dataTables settings object
14815	 *  @param {node} nHeader automatically detect the layout from this node - optional
14816	 *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
14817	 *  @returns array {node} aReturn list of unique th's
14818	 *  @memberof DataTable#oApi
14819	 */
14820	function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
14821	{
14822		var aReturn = [];
14823		if ( !aLayout )
14824		{
14825			aLayout = oSettings.aoHeader;
14826			if ( nHeader )
14827			{
14828				aLayout = [];
14829				_fnDetectHeader( aLayout, nHeader );
14830			}
14831		}
14832	
14833		for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
14834		{
14835			for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
14836			{
14837				if ( aLayout[i][j].unique &&
14838					 (!aReturn[j] || !oSettings.bSortCellsTop) )
14839				{
14840					aReturn[j] = aLayout[i][j].cell;
14841				}
14842			}
14843		}
14844	
14845		return aReturn;
14846	}
14847	
14848	/**
14849	 * 
vendor: 19,882 bytes, lines 14849-15508
14849Create an Ajax call based on the table's settings, taking into account that
14850	 * parameters can have multiple forms, and backwards compatibility.
14851	 *
14852	 * @param {object} oSettings dataTables settings object
14853	 * @param {array} data Data to send to the server, required by
14854	 *     DataTables - may be augmented by developer callbacks
14855	 * @param {function} fn Callback function to run when data is obtained
14856	 */
14857	function _fnBuildAjax( oSettings, data, fn )
14858	{
14859		// Compatibility with 1.9-, allow fnServerData and event to manipulate
14860		_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
14861	
14862		// Convert to object based for 1.10+ if using the old array scheme which can
14863		// come from server-side processing or serverParams
14864		if ( data && Array.isArray(data) ) {
14865			var tmp = {};
14866			var rbracket = /(.*?)\[\]$/;
14867	
14868			$.each( data, function (key, val) {
14869				var match = val.name.match(rbracket);
14870	
14871				if ( match ) {
14872					// Support for arrays
14873					var name = match[0];
14874	
14875					if ( ! tmp[ name ] ) {
14876						tmp[ name ] = [];
14877					}
14878					tmp[ name ].push( val.value );
14879				}
14880				else {
14881					tmp[val.name] = val.value;
14882				}
14883			} );
14884			data = tmp;
14885		}
14886	
14887		var ajaxData;
14888		var ajax = oSettings.ajax;
14889		var instance = oSettings.oInstance;
14890		var callback = function ( json ) {
14891			var status = oSettings.jqXhr
14892				? oSettings.jqXhr.status
14893				: null;
14894	
14895			if ( json === null || (typeof status === 'number' && status == 204 ) ) {
14896				json = {};
14897				_fnAjaxDataSrc( oSettings, json, [] );
14898			}
14899	
14900			var error = json.error || json.sError;
14901			if ( error ) {
14902				_fnLog( oSettings, 0, error );
14903			}
14904	
14905			oSettings.json = json;
14906	
14907			_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
14908			fn( json );
14909		};
14910	
14911		if ( $.isPlainObject( ajax ) && ajax.data )
14912		{
14913			ajaxData = ajax.data;
14914	
14915			var newData = typeof ajaxData === 'function' ?
14916				ajaxData( data, oSettings ) :  // fn can manipulate data or return
14917				ajaxData;                      // an object object or array to merge
14918	
14919			// If the function returned something, use that alone
14920			data = typeof ajaxData === 'function' && newData ?
14921				newData :
14922				$.extend( true, data, newData );
14923	
14924			// Remove the data property as we've resolved it already and don't want
14925			// jQuery to do it again (it is restored at the end of the function)
14926			delete ajax.data;
14927		}
14928	
14929		var baseAjax = {
14930			"data": data,
14931			"success": callback,
14932			"dataType": "json",
14933			"cache": false,
14934			"type": oSettings.sServerMethod,
14935			"error": function (xhr, error, thrown) {
14936				var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
14937	
14938				if ( $.inArray( true, ret ) === -1 ) {
14939					if ( error == "parsererror" ) {
14940						_fnLog( oSettings, 0, 'Invalid JSON response', 1 );
14941					}
14942					else if ( xhr.readyState === 4 ) {
14943						_fnLog( oSettings, 0, 'Ajax error', 7 );
14944					}
14945				}
14946	
14947				_fnProcessingDisplay( oSettings, false );
14948			}
14949		};
14950	
14951		// Store the data submitted for the API
14952		oSettings.oAjaxData = data;
14953	
14954		// Allow plug-ins and external processes to modify the data
14955		_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
14956	
14957		if ( oSettings.fnServerData )
14958		{
14959			// DataTables 1.9- compatibility
14960			oSettings.fnServerData.call( instance,
14961				oSettings.sAjaxSource,
14962				$.map( data, function (val, key) { // Need to convert back to 1.9 trad format
14963					return { name: key, value: val };
14964				} ),
14965				callback,
14966				oSettings
14967			);
14968		}
14969		else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
14970		{
14971			// DataTables 1.9- compatibility
14972			oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
14973				url: ajax || oSettings.sAjaxSource
14974			} ) );
14975		}
14976		else if ( typeof ajax === 'function' )
14977		{
14978			// Is a function - let the caller define what needs to be done
14979			oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
14980		}
14981		else
14982		{
14983			// Object to extend the base settings
14984			oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
14985	
14986			// Restore for next time around
14987			ajax.data = ajaxData;
14988		}
14989	}
14990	
14991	
14992	/**
14993	 * Update the table using an Ajax call
14994	 *  @param {object} settings dataTables settings object
14995	 *  @returns {boolean} Block the table drawing or not
14996	 *  @memberof DataTable#oApi
14997	 */
14998	function _fnAjaxUpdate( settings )
14999	{
15000		settings.iDraw++;
15001		_fnProcessingDisplay( settings, true );
15002	
15003		_fnBuildAjax(
15004			settings,
15005			_fnAjaxParameters( settings ),
15006			function(json) {
15007				_fnAjaxUpdateDraw( settings, json );
15008			}
15009		);
15010	}
15011	
15012	
15013	/**
15014	 * Build up the parameters in an object needed for a server-side processing
15015	 * request. Note that this is basically done twice, is different ways - a modern
15016	 * method which is used by default in DataTables 1.10 which uses objects and
15017	 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
15018	 * the sAjaxSource option is used in the initialisation, or the legacyAjax
15019	 * option is set.
15020	 *  @param {object} oSettings dataTables settings object
15021	 *  @returns {bool} block the table drawing or not
15022	 *  @memberof DataTable#oApi
15023	 */
15024	function _fnAjaxParameters( settings )
15025	{
15026		var
15027			columns = settings.aoColumns,
15028			columnCount = columns.length,
15029			features = settings.oFeatures,
15030			preSearch = settings.oPreviousSearch,
15031			preColSearch = settings.aoPreSearchCols,
15032			i, data = [], dataProp, column, columnSearch,
15033			sort = _fnSortFlatten( settings ),
15034			displayStart = settings._iDisplayStart,
15035			displayLength = features.bPaginate !== false ?
15036				settings._iDisplayLength :
15037				-1;
15038	
15039		var param = function ( name, value ) {
15040			data.push( { 'name': name, 'value': value } );
15041		};
15042	
15043		// DataTables 1.9- compatible method
15044		param( 'sEcho',          settings.iDraw );
15045		param( 'iColumns',       columnCount );
15046		param( 'sColumns',       _pluck( columns, 'sName' ).join(',') );
15047		param( 'iDisplayStart',  displayStart );
15048		param( 'iDisplayLength', displayLength );
15049	
15050		// DataTables 1.10+ method
15051		var d = {
15052			draw:    settings.iDraw,
15053			columns: [],
15054			order:   [],
15055			start:   displayStart,
15056			length:  displayLength,
15057			search:  {
15058				value: preSearch.sSearch,
15059				regex: preSearch.bRegex
15060			}
15061		};
15062	
15063		for ( i=0 ; i<columnCount ; i++ ) {
15064			column = columns[i];
15065			columnSearch = preColSearch[i];
15066			dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
15067	
15068			d.columns.push( {
15069				data:       dataProp,
15070				name:       column.sName,
15071				searchable: column.bSearchable,
15072				orderable:  column.bSortable,
15073				search:     {
15074					value: columnSearch.sSearch,
15075					regex: columnSearch.bRegex
15076				}
15077			} );
15078	
15079			param( "mDataProp_"+i, dataProp );
15080	
15081			if ( features.bFilter ) {
15082				param( 'sSearch_'+i,     columnSearch.sSearch );
15083				param( 'bRegex_'+i,      columnSearch.bRegex );
15084				param( 'bSearchable_'+i, column.bSearchable );
15085			}
15086	
15087			if ( features.bSort ) {
15088				param( 'bSortable_'+i, column.bSortable );
15089			}
15090		}
15091	
15092		if ( features.bFilter ) {
15093			param( 'sSearch', preSearch.sSearch );
15094			param( 'bRegex', preSearch.bRegex );
15095		}
15096	
15097		if ( features.bSort ) {
15098			$.each( sort, function ( i, val ) {
15099				d.order.push( { column: val.col, dir: val.dir } );
15100	
15101				param( 'iSortCol_'+i, val.col );
15102				param( 'sSortDir_'+i, val.dir );
15103			} );
15104	
15105			param( 'iSortingCols', sort.length );
15106		}
15107	
15108		// If the legacy.ajax parameter is null, then we automatically decide which
15109		// form to use, based on sAjaxSource
15110		var legacy = DataTable.ext.legacy.ajax;
15111		if ( legacy === null ) {
15112			return settings.sAjaxSource ? data : d;
15113		}
15114	
15115		// Otherwise, if legacy has been specified then we use that to decide on the
15116		// form
15117		return legacy ? data : d;
15118	}
15119	
15120	
15121	/**
15122	 * Data the data from the server (nuking the old) and redraw the table
15123	 *  @param {object} oSettings dataTables settings object
15124	 *  @param {object} json json data return from the server.
15125	 *  @param {string} json.sEcho Tracking flag for DataTables to match requests
15126	 *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
15127	 *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
15128	 *  @param {array} json.aaData The data to display on this page
15129	 *  @param {string} [json.sColumns] Column ordering (sName, comma separated)
15130	 *  @memberof DataTable#oApi
15131	 */
15132	function _fnAjaxUpdateDraw ( settings, json )
15133	{
15134		// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
15135		// Support both
15136		var compat = function ( old, modern ) {
15137			return json[old] !== undefined ? json[old] : json[modern];
15138		};
15139	
15140		var data = _fnAjaxDataSrc( settings, json );
15141		var draw            = compat( 'sEcho',                'draw' );
15142		var recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );
15143		var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
15144	
15145		if ( draw !== undefined ) {
15146			// Protect against out of sequence returns
15147			if ( draw*1 < settings.iDraw ) {
15148				return;
15149			}
15150			settings.iDraw = draw * 1;
15151		}
15152	
15153		// No data in returned object, so rather than an array, we show an empty table
15154		if ( ! data ) {
15155			data = [];
15156		}
15157	
15158		_fnClearTable( settings );
15159		settings._iRecordsTotal   = parseInt(recordsTotal, 10);
15160		settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
15161	
15162		for ( var i=0, ien=data.length ; i<ien ; i++ ) {
15163			_fnAddData( settings, data[i] );
15164		}
15165		settings.aiDisplay = settings.aiDisplayMaster.slice();
15166	
15167		_fnDraw( settings, true );
15168	
15169		if ( ! settings._bInitComplete ) {
15170			_fnInitComplete( settings, json );
15171		}
15172	
15173		_fnProcessingDisplay( settings, false );
15174	}
15175	
15176	
15177	/**
15178	 * Get the data from the JSON data source to use for drawing a table. Using
15179	 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
15180	 * source object, or from a processing function.
15181	 *  @param {object} oSettings dataTables settings object
15182	 *  @param  {object} json Data source object / array from the server
15183	 *  @return {array} Array of data to use
15184	 */
15185	 function _fnAjaxDataSrc ( oSettings, json, write )
15186	 {
15187		var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
15188			oSettings.ajax.dataSrc :
15189			oSettings.sAjaxDataProp; // Compatibility with 1.9-.
15190	
15191		if ( ! write ) {
15192			if ( dataSrc === 'data' ) {
15193				// If the default, then we still want to support the old style, and safely ignore
15194				// it if possible
15195				return json.aaData || json[dataSrc];
15196			}
15197	
15198			return dataSrc !== "" ?
15199				_fnGetObjectDataFn( dataSrc )( json ) :
15200				json;
15201		}
15202	
15203		// set
15204		_fnSetObjectDataFn( dataSrc )( json, write );
15205	}
15206	
15207	/**
15208	 * Generate the node required for filtering text
15209	 *  @returns {node} Filter control element
15210	 *  @param {object} oSettings dataTables settings object
15211	 *  @memberof DataTable#oApi
15212	 */
15213	function _fnFeatureHtmlFilter ( settings )
15214	{
15215		var classes = settings.oClasses;
15216		var tableId = settings.sTableId;
15217		var language = settings.oLanguage;
15218		var previousSearch = settings.oPreviousSearch;
15219		var features = settings.aanFeatures;
15220		var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
15221	
15222		var str = language.sSearch;
15223		str = str.match(/_INPUT_/) ?
15224			str.replace('_INPUT_', input) :
15225			str+input;
15226	
15227		var filter = $('<div/>', {
15228				'id': ! features.f ? tableId+'_filter' : null,
15229				'class': classes.sFilter
15230			} )
15231			.append( $('<label/>' ).append( str ) );
15232	
15233		var searchFn = function(event) {
15234			/* Update all other filter input elements for the new display */
15235			var n = features.f;
15236			var val = !this.value ? "" : this.value; // mental IE8 fix :-(
15237			if(previousSearch.return && event.key !== "Enter") {
15238				return;
15239			}
15240			/* Now do the filter */
15241			if ( val != previousSearch.sSearch ) {
15242				_fnFilterComplete( settings, {
15243					"sSearch": val,
15244					"bRegex": previousSearch.bRegex,
15245					"bSmart": previousSearch.bSmart ,
15246					"bCaseInsensitive": previousSearch.bCaseInsensitive,
15247					"return": previousSearch.return
15248				} );
15249	
15250				// Need to redraw, without resorting
15251				settings._iDisplayStart = 0;
15252				_fnDraw( settings );
15253			}
15254		};
15255	
15256		var searchDelay = settings.searchDelay !== null ?
15257			settings.searchDelay :
15258			_fnDataSource( settings ) === 'ssp' ?
15259				400 :
15260				0;
15261	
15262		var jqFilter = $('input', filter)
15263			.val( previousSearch.sSearch )
15264			.attr( 'placeholder', language.sSearchPlaceholder )
15265			.on(
15266				'keyup.DT search.DT input.DT paste.DT cut.DT',
15267				searchDelay ?
15268					_fnThrottle( searchFn, searchDelay ) :
15269					searchFn
15270			)
15271			.on( 'mouseup', function(e) {
15272				// Edge fix! Edge 17 does not trigger anything other than mouse events when clicking
15273				// on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn`
15274				// checks the value to see if it has changed. In other browsers it won't have.
15275				setTimeout( function () {
15276					searchFn.call(jqFilter[0], e);
15277				}, 10);
15278			} )
15279			.on( 'keypress.DT', function(e) {
15280				/* Prevent form submission */
15281				if ( e.keyCode == 13 ) {
15282					return false;
15283				}
15284			} )
15285			.attr('aria-controls', tableId);
15286	
15287		// Update the input elements whenever the table is filtered
15288		$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
15289			if ( settings === s ) {
15290				// IE9 throws an 'unknown error' if document.activeElement is used
15291				// inside an iframe or frame...
15292				try {
15293					if ( jqFilter[0] !== document.activeElement ) {
15294						jqFilter.val( previousSearch.sSearch );
15295					}
15296				}
15297				catch ( e ) {}
15298			}
15299		} );
15300	
15301		return filter[0];
15302	}
15303	
15304	
15305	/**
15306	 * Filter the table using both the global filter and column based filtering
15307	 *  @param {object} oSettings dataTables settings object
15308	 *  @param {object} oSearch search information
15309	 *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
15310	 *  @memberof DataTable#oApi
15311	 */
15312	function _fnFilterComplete ( oSettings, oInput, iForce )
15313	{
15314		var oPrevSearch = oSettings.oPreviousSearch;
15315		var aoPrevSearch = oSettings.aoPreSearchCols;
15316		var fnSaveFilter = function ( oFilter ) {
15317			/* Save the filtering values */
15318			oPrevSearch.sSearch = oFilter.sSearch;
15319			oPrevSearch.bRegex = oFilter.bRegex;
15320			oPrevSearch.bSmart = oFilter.bSmart;
15321			oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
15322			oPrevSearch.return = oFilter.return;
15323		};
15324		var fnRegex = function ( o ) {
15325			// Backwards compatibility with the bEscapeRegex option
15326			return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
15327		};
15328	
15329		// Resolve any column types that are unknown due to addition or invalidation
15330		// @todo As per sort - can this be moved into an event handler?
15331		_fnColumnTypes( oSettings );
15332	
15333		/* In server-side processing all filtering is done by the server, so no point hanging around here */
15334		if ( _fnDataSource( oSettings ) != 'ssp' )
15335		{
15336			/* Global filter */
15337			_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive, oInput.return );
15338			fnSaveFilter( oInput );
15339	
15340			/* Now do the individual column filter */
15341			for ( var i=0 ; i<aoPrevSearch.length ; i++ )
15342			{
15343				_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
15344					aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
15345			}
15346	
15347			/* Custom filtering */
15348			_fnFilterCustom( oSettings );
15349		}
15350		else
15351		{
15352			fnSaveFilter( oInput );
15353		}
15354	
15355		/* Tell the draw function we have been filtering */
15356		oSettings.bFiltered = true;
15357		_fnCallbackFire( oSettings, null, 'search', [oSettings] );
15358	}
15359	
15360	
15361	/**
15362	 * Apply custom filtering functions
15363	 *  @param {object} oSettings dataTables settings object
15364	 *  @memberof DataTable#oApi
15365	 */
15366	function _fnFilterCustom( settings )
15367	{
15368		var filters = DataTable.ext.search;
15369		var displayRows = settings.aiDisplay;
15370		var row, rowIdx;
15371	
15372		for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
15373			var rows = [];
15374	
15375			// Loop over each row and see if it should be included
15376			for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
15377				rowIdx = displayRows[ j ];
15378				row = settings.aoData[ rowIdx ];
15379	
15380				if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
15381					rows.push( rowIdx );
15382				}
15383			}
15384	
15385			// So the array reference doesn't break set the results into the
15386			// existing array
15387			displayRows.length = 0;
15388			$.merge( displayRows, rows );
15389		}
15390	}
15391	
15392	
15393	/**
15394	 * Filter the table on a per-column basis
15395	 *  @param {object} oSettings dataTables settings object
15396	 *  @param {string} sInput string to filter on
15397	 *  @param {int} iColumn column to filter
15398	 *  @param {bool} bRegex treat search string as a regular expression or not
15399	 *  @param {bool} bSmart use smart filtering or not
15400	 *  @param {bool} bCaseInsensitive Do case insensitive matching or not
15401	 *  @memberof DataTable#oApi
15402	 */
15403	function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
15404	{
15405		if ( searchStr === '' ) {
15406			return;
15407		}
15408	
15409		var data;
15410		var out = [];
15411		var display = settings.aiDisplay;
15412		var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
15413	
15414		for ( var i=0 ; i<display.length ; i++ ) {
15415			data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
15416	
15417			if ( rpSearch.test( data ) ) {
15418				out.push( display[i] );
15419			}
15420		}
15421	
15422		settings.aiDisplay = out;
15423	}
15424	
15425	
15426	/**
15427	 * Filter the data table based on user input and draw the table
15428	 *  @param {object} settings dataTables settings object
15429	 *  @param {string} input string to filter on
15430	 *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
15431	 *  @param {bool} regex treat as a regular expression or not
15432	 *  @param {bool} smart perform smart filtering or not
15433	 *  @param {bool} caseInsensitive Do case insensitive matching or not
15434	 *  @memberof DataTable#oApi
15435	 */
15436	function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
15437	{
15438		var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
15439		var prevSearch = settings.oPreviousSearch.sSearch;
15440		var displayMaster = settings.aiDisplayMaster;
15441		var display, invalidated, i;
15442		var filtered = [];
15443	
15444		// Need to take account of custom filtering functions - always filter
15445		if ( DataTable.ext.search.length !== 0 ) {
15446			force = true;
15447		}
15448	
15449		// Check if any of the rows were invalidated
15450		invalidated = _fnFilterData( settings );
15451	
15452		// If the input is blank - we just want the full data set
15453		if ( input.length <= 0 ) {
15454			settings.aiDisplay = displayMaster.slice();
15455		}
15456		else {
15457			// New search - start from the master array
15458			if ( invalidated ||
15459				 force ||
15460				 regex ||
15461				 prevSearch.length > input.length ||
15462				 input.indexOf(prevSearch) !== 0 ||
15463				 settings.bSorted // On resort, the display master needs to be
15464				                  // re-filtered since indexes will have changed
15465			) {
15466				settings.aiDisplay = displayMaster.slice();
15467			}
15468	
15469			// Search the display array
15470			display = settings.aiDisplay;
15471	
15472			for ( i=0 ; i<display.length ; i++ ) {
15473				if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
15474					filtered.push( display[i] );
15475				}
15476			}
15477	
15478			settings.aiDisplay = filtered;
15479		}
15480	}
15481	
15482	
15483	/**
15484	 * Build a regular expression object suitable for searching a table
15485	 *  @param {string} sSearch string to search for
15486	 *  @param {bool} bRegex treat as a regular expression or not
15487	 *  @param {bool} bSmart perform smart filtering or not
15488	 *  @param {bool} bCaseInsensitive Do case insensitive matching or not
15489	 *  @returns {RegExp} constructed object
15490	 *  @memberof DataTable#oApi
15491	 */
15492	function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
15493	{
15494		search = regex ?
15495			search :
15496			_fnEscapeRegex( search );
15497		
15498		if ( smart ) {
15499			/* For smart filtering we want to allow the search to work regardless of
15500			 * word order. We also want double quoted text to be preserved, so word
15501			 * order is important - a la google. So this is what we want to
15502			 * generate:
15503			 * 
15504			 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
15505			 */
15506			var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
15507				if ( word.charAt(0) === '"' ) {
15508					var m = word.match( /^"(.*)"
vendor: 13,994 bytes, lines 15508-16041
15508$/ );
15509					word = m ? m[1] : word;
15510				}
15511	
15512				return word.replace('"', '');
15513			} );
15514	
15515			search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
15516		}
15517	
15518		return new RegExp( search, caseInsensitive ? 'i' : '' );
15519	}
15520	
15521	
15522	/**
15523	 * Escape a string such that it can be used in a regular expression
15524	 *  @param {string} sVal string to escape
15525	 *  @returns {string} escaped string
15526	 *  @memberof DataTable#oApi
15527	 */
15528	var _fnEscapeRegex = DataTable.util.escapeRegex;
15529	
15530	var __filter_div = $('<div>')[0];
15531	var __filter_div_textContent = __filter_div.textContent !== undefined;
15532	
15533	// Update the filtering data for each row if needed (by invalidation or first run)
15534	function _fnFilterData ( settings )
15535	{
15536		var columns = settings.aoColumns;
15537		var column;
15538		var i, j, ien, jen, filterData, cellData, row;
15539		var wasInvalidated = false;
15540	
15541		for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
15542			row = settings.aoData[i];
15543	
15544			if ( ! row._aFilterData ) {
15545				filterData = [];
15546	
15547				for ( j=0, jen=columns.length ; j<jen ; j++ ) {
15548					column = columns[j];
15549	
15550					if ( column.bSearchable ) {
15551						cellData = _fnGetCellData( settings, i, j, 'filter' );
15552	
15553						// Search in DataTables 1.10 is string based. In 1.11 this
15554						// should be altered to also allow strict type checking.
15555						if ( cellData === null ) {
15556							cellData = '';
15557						}
15558	
15559						if ( typeof cellData !== 'string' && cellData.toString ) {
15560							cellData = cellData.toString();
15561						}
15562					}
15563					else {
15564						cellData = '';
15565					}
15566	
15567					// If it looks like there is an HTML entity in the string,
15568					// attempt to decode it so sorting works as expected. Note that
15569					// we could use a single line of jQuery to do this, but the DOM
15570					// method used here is much faster http://jsperf.com/html-decode
15571					if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
15572						__filter_div.innerHTML = cellData;
15573						cellData = __filter_div_textContent ?
15574							__filter_div.textContent :
15575							__filter_div.innerText;
15576					}
15577	
15578					if ( cellData.replace ) {
15579						cellData = cellData.replace(/[\r\n\u2028]/g, '');
15580					}
15581	
15582					filterData.push( cellData );
15583				}
15584	
15585				row._aFilterData = filterData;
15586				row._sFilterRow = filterData.join('  ');
15587				wasInvalidated = true;
15588			}
15589		}
15590	
15591		return wasInvalidated;
15592	}
15593	
15594	
15595	/**
15596	 * Convert from the internal Hungarian notation to camelCase for external
15597	 * interaction
15598	 *  @param {object} obj Object to convert
15599	 *  @returns {object} Inverted object
15600	 *  @memberof DataTable#oApi
15601	 */
15602	function _fnSearchToCamel ( obj )
15603	{
15604		return {
15605			search:          obj.sSearch,
15606			smart:           obj.bSmart,
15607			regex:           obj.bRegex,
15608			caseInsensitive: obj.bCaseInsensitive
15609		};
15610	}
15611	
15612	
15613	
15614	/**
15615	 * Convert from camelCase notation to the internal Hungarian. We could use the
15616	 * Hungarian convert function here, but this is cleaner
15617	 *  @param {object} obj Object to convert
15618	 *  @returns {object} Inverted object
15619	 *  @memberof DataTable#oApi
15620	 */
15621	function _fnSearchToHung ( obj )
15622	{
15623		return {
15624			sSearch:          obj.search,
15625			bSmart:           obj.smart,
15626			bRegex:           obj.regex,
15627			bCaseInsensitive: obj.caseInsensitive
15628		};
15629	}
15630	
15631	/**
15632	 * Generate the node required for the info display
15633	 *  @param {object} oSettings dataTables settings object
15634	 *  @returns {node} Information element
15635	 *  @memberof DataTable#oApi
15636	 */
15637	function _fnFeatureHtmlInfo ( settings )
15638	{
15639		var
15640			tid = settings.sTableId,
15641			nodes = settings.aanFeatures.i,
15642			n = $('<div/>', {
15643				'class': settings.oClasses.sInfo,
15644				'id': ! nodes ? tid+'_info' : null
15645			} );
15646	
15647		if ( ! nodes ) {
15648			// Update display on each draw
15649			settings.aoDrawCallback.push( {
15650				"fn": _fnUpdateInfo,
15651				"sName": "information"
15652			} );
15653	
15654			n
15655				.attr( 'role', 'status' )
15656				.attr( 'aria-live', 'polite' );
15657	
15658			// Table is described by our info div
15659			$(settings.nTable).attr( 'aria-describedby', tid+'_info' );
15660		}
15661	
15662		return n[0];
15663	}
15664	
15665	
15666	/**
15667	 * Update the information elements in the display
15668	 *  @param {object} settings dataTables settings object
15669	 *  @memberof DataTable#oApi
15670	 */
15671	function _fnUpdateInfo ( settings )
15672	{
15673		/* Show information about the table */
15674		var nodes = settings.aanFeatures.i;
15675		if ( nodes.length === 0 ) {
15676			return;
15677		}
15678	
15679		var
15680			lang  = settings.oLanguage,
15681			start = settings._iDisplayStart+1,
15682			end   = settings.fnDisplayEnd(),
15683			max   = settings.fnRecordsTotal(),
15684			total = settings.fnRecordsDisplay(),
15685			out   = total ?
15686				lang.sInfo :
15687				lang.sInfoEmpty;
15688	
15689		if ( total !== max ) {
15690			/* Record set after filtering */
15691			out += ' ' + lang.sInfoFiltered;
15692		}
15693	
15694		// Convert the macros
15695		out += lang.sInfoPostFix;
15696		out = _fnInfoMacros( settings, out );
15697	
15698		var callback = lang.fnInfoCallback;
15699		if ( callback !== null ) {
15700			out = callback.call( settings.oInstance,
15701				settings, start, end, max, total, out
15702			);
15703		}
15704	
15705		$(nodes).html( out );
15706	}
15707	
15708	
15709	function _fnInfoMacros ( settings, str )
15710	{
15711		// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
15712		// internally
15713		var
15714			formatter  = settings.fnFormatNumber,
15715			start      = settings._iDisplayStart+1,
15716			len        = settings._iDisplayLength,
15717			vis        = settings.fnRecordsDisplay(),
15718			all        = len === -1;
15719	
15720		return str.
15721			replace(/_START_/g, formatter.call( settings, start ) ).
15722			replace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).
15723			replace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).
15724			replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
15725			replace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
15726			replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
15727	}
15728	
15729	
15730	
15731	/**
15732	 * Draw the table for the first time, adding all required features
15733	 *  @param {object} settings dataTables settings object
15734	 *  @memberof DataTable#oApi
15735	 */
15736	function _fnInitialise ( settings )
15737	{
15738		var i, iLen, iAjaxStart=settings.iInitDisplayStart;
15739		var columns = settings.aoColumns, column;
15740		var features = settings.oFeatures;
15741		var deferLoading = settings.bDeferLoading; // value modified by the draw
15742	
15743		/* Ensure that the table data is fully initialised */
15744		if ( ! settings.bInitialised ) {
15745			setTimeout( function(){ _fnInitialise( settings ); }, 200 );
15746			return;
15747		}
15748	
15749		/* Show the display HTML options */
15750		_fnAddOptionsHtml( settings );
15751	
15752		/* Build and draw the header / footer for the table */
15753		_fnBuildHead( settings );
15754		_fnDrawHead( settings, settings.aoHeader );
15755		_fnDrawHead( settings, settings.aoFooter );
15756	
15757		/* Okay to show that something is going on now */
15758		_fnProcessingDisplay( settings, true );
15759	
15760		/* Calculate sizes for columns */
15761		if ( features.bAutoWidth ) {
15762			_fnCalculateColumnWidths( settings );
15763		}
15764	
15765		for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
15766			column = columns[i];
15767	
15768			if ( column.sWidth ) {
15769				column.nTh.style.width = _fnStringToCss( column.sWidth );
15770			}
15771		}
15772	
15773		_fnCallbackFire( settings, null, 'preInit', [settings] );
15774	
15775		// If there is default sorting required - let's do it. The sort function
15776		// will do the drawing for us. Otherwise we draw the table regardless of the
15777		// Ajax source - this allows the table to look initialised for Ajax sourcing
15778		// data (show 'loading' message possibly)
15779		_fnReDraw( settings );
15780	
15781		// Server-side processing init complete is done by _fnAjaxUpdateDraw
15782		var dataSrc = _fnDataSource( settings );
15783		if ( dataSrc != 'ssp' || deferLoading ) {
15784			// if there is an ajax source load the data
15785			if ( dataSrc == 'ajax' ) {
15786				_fnBuildAjax( settings, [], function(json) {
15787					var aData = _fnAjaxDataSrc( settings, json );
15788	
15789					// Got the data - add it to the table
15790					for ( i=0 ; i<aData.length ; i++ ) {
15791						_fnAddData( settings, aData[i] );
15792					}
15793	
15794					// Reset the init display for cookie saving. We've already done
15795					// a filter, and therefore cleared it before. So we need to make
15796					// it appear 'fresh'
15797					settings.iInitDisplayStart = iAjaxStart;
15798	
15799					_fnReDraw( settings );
15800	
15801					_fnProcessingDisplay( settings, false );
15802					_fnInitComplete( settings, json );
15803				}, settings );
15804			}
15805			else {
15806				_fnProcessingDisplay( settings, false );
15807				_fnInitComplete( settings );
15808			}
15809		}
15810	}
15811	
15812	
15813	/**
15814	 * Draw the table for the first time, adding all required features
15815	 *  @param {object} oSettings dataTables settings object
15816	 *  @param {object} [json] JSON from the server that completed the table, if using Ajax source
15817	 *    with client-side processing (optional)
15818	 *  @memberof DataTable#oApi
15819	 */
15820	function _fnInitComplete ( settings, json )
15821	{
15822		settings._bInitComplete = true;
15823	
15824		// When data was added after the initialisation (data or Ajax) we need to
15825		// calculate the column sizing
15826		if ( json || settings.oInit.aaData ) {
15827			_fnAdjustColumnSizing( settings );
15828		}
15829	
15830		_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
15831		_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
15832	}
15833	
15834	
15835	function _fnLengthChange ( settings, val )
15836	{
15837		var len = parseInt( val, 10 );
15838		settings._iDisplayLength = len;
15839	
15840		_fnLengthOverflow( settings );
15841	
15842		// Fire length change event
15843		_fnCallbackFire( settings, null, 'length', [settings, len] );
15844	}
15845	
15846	
15847	/**
15848	 * Generate the node required for user display length changing
15849	 *  @param {object} settings dataTables settings object
15850	 *  @returns {node} Display length feature node
15851	 *  @memberof DataTable#oApi
15852	 */
15853	function _fnFeatureHtmlLength ( settings )
15854	{
15855		var
15856			classes  = settings.oClasses,
15857			tableId  = settings.sTableId,
15858			menu     = settings.aLengthMenu,
15859			d2       = Array.isArray( menu[0] ),
15860			lengths  = d2 ? menu[0] : menu,
15861			language = d2 ? menu[1] : menu;
15862	
15863		var select = $('<select/>', {
15864			'name':          tableId+'_length',
15865			'aria-controls': tableId,
15866			'class':         classes.sLengthSelect
15867		} );
15868	
15869		for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
15870			select[0][ i ] = new Option(
15871				typeof language[i] === 'number' ?
15872					settings.fnFormatNumber( language[i] ) :
15873					language[i],
15874				lengths[i]
15875			);
15876		}
15877	
15878		var div = $('<div><label/></div>').addClass( classes.sLength );
15879		if ( ! settings.aanFeatures.l ) {
15880			div[0].id = tableId+'_length';
15881		}
15882	
15883		div.children().append(
15884			settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
15885		);
15886	
15887		// Can't use `select` variable as user might provide their own and the
15888		// reference is broken by the use of outerHTML
15889		$('select', div)
15890			.val( settings._iDisplayLength )
15891			.on( 'change.DT', function(e) {
15892				_fnLengthChange( settings, $(this).val() );
15893				_fnDraw( settings );
15894			} );
15895	
15896		// Update node value whenever anything changes the table's length
15897		$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
15898			if ( settings === s ) {
15899				$('select', div).val( len );
15900			}
15901		} );
15902	
15903		return div[0];
15904	}
15905	
15906	
15907	
15908	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
15909	 * Note that most of the paging logic is done in
15910	 * DataTable.ext.pager
15911	 */
15912	
15913	/**
15914	 * Generate the node required for default pagination
15915	 *  @param {object} oSettings dataTables settings object
15916	 *  @returns {node} Pagination feature node
15917	 *  @memberof DataTable#oApi
15918	 */
15919	function _fnFeatureHtmlPaginate ( settings )
15920	{
15921		var
15922			type   = settings.sPaginationType,
15923			plugin = DataTable.ext.pager[ type ],
15924			modern = typeof plugin === 'function',
15925			redraw = function( settings ) {
15926				_fnDraw( settings );
15927			},
15928			node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
15929			features = settings.aanFeatures;
15930	
15931		if ( ! modern ) {
15932			plugin.fnInit( settings, node, redraw );
15933		}
15934	
15935		/* Add a draw callback for the pagination on first instance, to update the paging display */
15936		if ( ! features.p )
15937		{
15938			node.id = settings.sTableId+'_paginate';
15939	
15940			settings.aoDrawCallback.push( {
15941				"fn": function( settings ) {
15942					if ( modern ) {
15943						var
15944							start      = settings._iDisplayStart,
15945							len        = settings._iDisplayLength,
15946							visRecords = settings.fnRecordsDisplay(),
15947							all        = len === -1,
15948							page = all ? 0 : Math.ceil( start / len ),
15949							pages = all ? 1 : Math.ceil( visRecords / len ),
15950							buttons = plugin(page, pages),
15951							i, ien;
15952	
15953						for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
15954							_fnRenderer( settings, 'pageButton' )(
15955								settings, features.p[i], i, buttons, page, pages
15956							);
15957						}
15958					}
15959					else {
15960						plugin.fnUpdate( settings, redraw );
15961					}
15962				},
15963				"sName": "pagination"
15964			} );
15965		}
15966	
15967		return node;
15968	}
15969	
15970	
15971	/**
15972	 * Alter the display settings to change the page
15973	 *  @param {object} settings DataTables settings object
15974	 *  @param {string|int} action Paging action to take: "first", "previous",
15975	 *    "next" or "last" or page number to jump to (integer)
15976	 *  @param [bool] redraw Automatically draw the update or not
15977	 *  @returns {bool} true page has changed, false - no change
15978	 *  @memberof DataTable#oApi
15979	 */
15980	function _fnPageChange ( settings, action, redraw )
15981	{
15982		var
15983			start     = settings._iDisplayStart,
15984			len       = settings._iDisplayLength,
15985			records   = settings.fnRecordsDisplay();
15986	
15987		if ( records === 0 || len === -1 )
15988		{
15989			start = 0;
15990		}
15991		else if ( typeof action === "number" )
15992		{
15993			start = action * len;
15994	
15995			if ( start > records )
15996			{
15997				start = 0;
15998			}
15999		}
16000		else if ( action == "first" )
16001		{
16002			start = 0;
16003		}
16004		else if ( action == "previous" )
16005		{
16006			start = len >= 0 ?
16007				start - len :
16008				0;
16009	
16010			if ( start < 0 )
16011			{
16012			  start = 0;
16013			}
16014		}
16015		else if ( action == "next" )
16016		{
16017			if ( start + len < records )
16018			{
16019				start += len;
16020			}
16021		}
16022		else if ( action == "last" )
16023		{
16024			start = Math.floor( (records-1) / len) * len;
16025		}
16026		else
16027		{
16028			_fnLog( settings, 0, "Unknown paging action: "+action, 5 );
16029		}
16030	
16031		var changed = settings._iDisplayStart !== start;
16032		settings._iDisplayStart = start;
16033	
16034		if ( changed ) {
16035			_fnCallbackFire( settings, null, 'page', [settings] );
16036	
16037			if ( redraw ) {
16038				_fnDraw( settings );
16039			}
16040		}
16041	
16041
16042		return changed;
16043	}
16044	
16045	
16046	
16047	/**
16048	 * Generate the node required for the processing node
16049	 *  @param {object} settings dataTables settings object
16050	 *  @returns {node} Processing element
16051	 *  @memberof DataTable#oApi
16052	 */
16053	function _fnFeatureHtmlProcessing ( settings )
16054	{
16055		return $('<div/>', {
16056				'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
16057				'class': settings.oClasses.sProcessing
16058			} )
16059			.html( settings.oLanguage.sProcessing 
vendor: 7,187 bytes, lines 16059-16309
16059)
16060			.insertBefore( settings.nTable )[0];
16061	}
16062	
16063	
16064	/**
16065	 * Display or hide the processing indicator
16066	 *  @param {object} settings dataTables settings object
16067	 *  @param {bool} show Show the processing indicator (true) or not (false)
16068	 *  @memberof DataTable#oApi
16069	 */
16070	function _fnProcessingDisplay ( settings, show )
16071	{
16072		if ( settings.oFeatures.bProcessing ) {
16073			$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
16074		}
16075	
16076		_fnCallbackFire( settings, null, 'processing', [settings, show] );
16077	}
16078	
16079	/**
16080	 * Add any control elements for the table - specifically scrolling
16081	 *  @param {object} settings dataTables settings object
16082	 *  @returns {node} Node to add to the DOM
16083	 *  @memberof DataTable#oApi
16084	 */
16085	function _fnFeatureHtmlTable ( settings )
16086	{
16087		var table = $(settings.nTable);
16088	
16089		// Scrolling from here on in
16090		var scroll = settings.oScroll;
16091	
16092		if ( scroll.sX === '' && scroll.sY === '' ) {
16093			return settings.nTable;
16094		}
16095	
16096		var scrollX = scroll.sX;
16097		var scrollY = scroll.sY;
16098		var classes = settings.oClasses;
16099		var caption = table.children('caption');
16100		var captionSide = caption.length ? caption[0]._captionSide : null;
16101		var headerClone = $( table[0].cloneNode(false) );
16102		var footerClone = $( table[0].cloneNode(false) );
16103		var footer = table.children('tfoot');
16104		var _div = '<div/>';
16105		var size = function ( s ) {
16106			return !s ? null : _fnStringToCss( s );
16107		};
16108	
16109		if ( ! footer.length ) {
16110			footer = null;
16111		}
16112	
16113		/*
16114		 * The HTML structure that we want to generate in this function is:
16115		 *  div - scroller
16116		 *    div - scroll head
16117		 *      div - scroll head inner
16118		 *        table - scroll head table
16119		 *          thead - thead
16120		 *    div - scroll body
16121		 *      table - table (master table)
16122		 *        thead - thead clone for sizing
16123		 *        tbody - tbody
16124		 *    div - scroll foot
16125		 *      div - scroll foot inner
16126		 *        table - scroll foot table
16127		 *          tfoot - tfoot
16128		 */
16129		var scroller = $( _div, { 'class': classes.sScrollWrapper } )
16130			.append(
16131				$(_div, { 'class': classes.sScrollHead } )
16132					.css( {
16133						overflow: 'hidden',
16134						position: 'relative',
16135						border: 0,
16136						width: scrollX ? size(scrollX) : '100%'
16137					} )
16138					.append(
16139						$(_div, { 'class': classes.sScrollHeadInner } )
16140							.css( {
16141								'box-sizing': 'content-box',
16142								width: scroll.sXInner || '100%'
16143							} )
16144							.append(
16145								headerClone
16146									.removeAttr('id')
16147									.css( 'margin-left', 0 )
16148									.append( captionSide === 'top' ? caption : null )
16149									.append(
16150										table.children('thead')
16151									)
16152							)
16153					)
16154			)
16155			.append(
16156				$(_div, { 'class': classes.sScrollBody } )
16157					.css( {
16158						position: 'relative',
16159						overflow: 'auto',
16160						width: size( scrollX )
16161					} )
16162					.append( table )
16163			);
16164	
16165		if ( footer ) {
16166			scroller.append(
16167				$(_div, { 'class': classes.sScrollFoot } )
16168					.css( {
16169						overflow: 'hidden',
16170						border: 0,
16171						width: scrollX ? size(scrollX) : '100%'
16172					} )
16173					.append(
16174						$(_div, { 'class': classes.sScrollFootInner } )
16175							.append(
16176								footerClone
16177									.removeAttr('id')
16178									.css( 'margin-left', 0 )
16179									.append( captionSide === 'bottom' ? caption : null )
16180									.append(
16181										table.children('tfoot')
16182									)
16183							)
16184					)
16185			);
16186		}
16187	
16188		var children = scroller.children();
16189		var scrollHead = children[0];
16190		var scrollBody = children[1];
16191		var scrollFoot = footer ? children[2] : null;
16192	
16193		// When the body is scrolled, then we also want to scroll the headers
16194		if ( scrollX ) {
16195			$(scrollBody).on( 'scroll.DT', function (e) {
16196				var scrollLeft = this.scrollLeft;
16197	
16198				scrollHead.scrollLeft = scrollLeft;
16199	
16200				if ( footer ) {
16201					scrollFoot.scrollLeft = scrollLeft;
16202				}
16203			} );
16204		}
16205	
16206		$(scrollBody).css('max-height', scrollY);
16207		if (! scroll.bCollapse) {
16208			$(scrollBody).css('height', scrollY);
16209		}
16210	
16211		settings.nScrollHead = scrollHead;
16212		settings.nScrollBody = scrollBody;
16213		settings.nScrollFoot = scrollFoot;
16214	
16215		// On redraw - align columns
16216		settings.aoDrawCallback.push( {
16217			"fn": _fnScrollDraw,
16218			"sName": "scrolling"
16219		} );
16220	
16221		return scroller[0];
16222	}
16223	
16224	
16225	
16226	/**
16227	 * Update the header, footer and body tables for resizing - i.e. column
16228	 * alignment.
16229	 *
16230	 * Welcome to the most horrible function DataTables. The process that this
16231	 * function follows is basically:
16232	 *   1. Re-create the table inside the scrolling div
16233	 *   2. Take live measurements from the DOM
16234	 *   3. Apply the measurements to align the columns
16235	 *   4. Clean up
16236	 *
16237	 *  @param {object} settings dataTables settings object
16238	 *  @memberof DataTable#oApi
16239	 */
16240	function _fnScrollDraw ( settings )
16241	{
16242		// Given that this is such a monster function, a lot of variables are use
16243		// to try and keep the minimised size as small as possible
16244		var
16245			scroll         = settings.oScroll,
16246			scrollX        = scroll.sX,
16247			scrollXInner   = scroll.sXInner,
16248			scrollY        = scroll.sY,
16249			barWidth       = scroll.iBarWidth,
16250			divHeader      = $(settings.nScrollHead),
16251			divHeaderStyle = divHeader[0].style,
16252			divHeaderInner = divHeader.children('div'),
16253			divHeaderInnerStyle = divHeaderInner[0].style,
16254			divHeaderTable = divHeaderInner.children('table'),
16255			divBodyEl      = settings.nScrollBody,
16256			divBody        = $(divBodyEl),
16257			divBodyStyle   = divBodyEl.style,
16258			divFooter      = $(settings.nScrollFoot),
16259			divFooterInner = divFooter.children('div'),
16260			divFooterTable = divFooterInner.children('table'),
16261			header         = $(settings.nTHead),
16262			table          = $(settings.nTable),
16263			tableEl        = table[0],
16264			tableStyle     = tableEl.style,
16265			footer         = settings.nTFoot ? $(settings.nTFoot) : null,
16266			browser        = settings.oBrowser,
16267			ie67           = browser.bScrollOversize,
16268			dtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),
16269			headerTrgEls, footerTrgEls,
16270			headerSrcEls, footerSrcEls,
16271			headerCopy, footerCopy,
16272			headerWidths=[], footerWidths=[],
16273			headerContent=[], footerContent=[],
16274			idx, correction, sanityWidth,
16275			zeroOut = function(nSizer) {
16276				var style = nSizer.style;
16277				style.paddingTop = "0";
16278				style.paddingBottom = "0";
16279				style.borderTopWidth = "0";
16280				style.borderBottomWidth = "0";
16281				style.height = 0;
16282			};
16283	
16284		// If the scrollbar visibility has changed from the last draw, we need to
16285		// adjust the column sizes as the table width will have changed to account
16286		// for the scrollbar
16287		var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
16288		
16289		if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
16290			settings.scrollBarVis = scrollBarVis;
16291			_fnAdjustColumnSizing( settings );
16292			return; // adjust column sizing will call this function again
16293		}
16294		else {
16295			settings.scrollBarVis = scrollBarVis;
16296		}
16297	
16298		/*
16299		 * 1. Re-create the table inside the scrolling div
16300		 */
16301	
16302		// Remove the old minimised thead and tfoot elements in the inner table
16303		table.children('thead, tfoot').remove();
16304	
16305		if ( footer ) {
16306			footerCopy = footer.clone().prependTo( table );
16307			footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
16308			footerSrcEls = footerCopy.find('tr');
16309		
vendor: 4,075 bytes, lines 16309-16436
16309}
16310	
16311		// Clone the current header and footer elements and then place it into the inner table
16312		headerCopy = header.clone().prependTo( table );
16313		headerTrgEls = header.find('tr'); // original header is in its own table
16314		headerSrcEls = headerCopy.find('tr');
16315		headerCopy.find('th, td').removeAttr('tabindex');
16316	
16317	
16318		/*
16319		 * 2. Take live measurements from the DOM - do not alter the DOM itself!
16320		 */
16321	
16322		// Remove old sizing and apply the calculated column widths
16323		// Get the unique column headers in the newly created (cloned) header. We want to apply the
16324		// calculated sizes to this header
16325		if ( ! scrollX )
16326		{
16327			divBodyStyle.width = '100%';
16328			divHeader[0].style.width = '100%';
16329		}
16330	
16331		$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
16332			idx = _fnVisibleToColumnIndex( settings, i );
16333			el.style.width = settings.aoColumns[idx].sWidth;
16334		} );
16335	
16336		if ( footer ) {
16337			_fnApplyToChildren( function(n) {
16338				n.style.width = "";
16339			}, footerSrcEls );
16340		}
16341	
16342		// Size the table as a whole
16343		sanityWidth = table.outerWidth();
16344		if ( scrollX === "" ) {
16345			// No x scrolling
16346			tableStyle.width = "100%";
16347	
16348			// IE7 will make the width of the table when 100% include the scrollbar
16349			// - which is shouldn't. When there is a scrollbar we need to take this
16350			// into account.
16351			if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
16352				divBody.css('overflow-y') == "scroll")
16353			) {
16354				tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
16355			}
16356	
16357			// Recalculate the sanity width
16358			sanityWidth = table.outerWidth();
16359		}
16360		else if ( scrollXInner !== "" ) {
16361			// legacy x scroll inner has been given - use it
16362			tableStyle.width = _fnStringToCss(scrollXInner);
16363	
16364			// Recalculate the sanity width
16365			sanityWidth = table.outerWidth();
16366		}
16367	
16368		// Hidden header should have zero height, so remove padding and borders. Then
16369		// set the width based on the real headers
16370	
16371		// Apply all styles in one pass
16372		_fnApplyToChildren( zeroOut, headerSrcEls );
16373	
16374		// Read all widths in next pass
16375		_fnApplyToChildren( function(nSizer) {
16376			var style = window.getComputedStyle ?
16377				window.getComputedStyle(nSizer).width :
16378				_fnStringToCss( $(nSizer).width() );
16379	
16380			headerContent.push( nSizer.innerHTML );
16381			headerWidths.push( style );
16382		}, headerSrcEls );
16383	
16384		// Apply all widths in final pass
16385		_fnApplyToChildren( function(nToSize, i) {
16386			nToSize.style.width = headerWidths[i];
16387		}, headerTrgEls );
16388	
16389		$(headerSrcEls).height(0);
16390	
16391		/* Same again with the footer if we have one */
16392		if ( footer )
16393		{
16394			_fnApplyToChildren( zeroOut, footerSrcEls );
16395	
16396			_fnApplyToChildren( function(nSizer) {
16397				footerContent.push( nSizer.innerHTML );
16398				footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
16399			}, footerSrcEls );
16400	
16401			_fnApplyToChildren( function(nToSize, i) {
16402				nToSize.style.width = footerWidths[i];
16403			}, footerTrgEls );
16404	
16405			$(footerSrcEls).height(0);
16406		}
16407	
16408	
16409		/*
16410		 * 3. Apply the measurements
16411		 */
16412	
16413		// "Hide" the header and footer that we used for the sizing. We need to keep
16414		// the content of the cell so that the width applied to the header and body
16415		// both match, but we want to hide it completely. We want to also fix their
16416		// width to what they currently are
16417		_fnApplyToChildren( function(nSizer, i) {
16418			nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>';
16419			nSizer.childNodes[0].style.height = "0";
16420			nSizer.childNodes[0].style.overflow = "hidden";
16421			nSizer.style.width = headerWidths[i];
16422		}, headerSrcEls );
16423	
16424		if ( footer )
16425		{
16426			_fnApplyToChildren( function(nSizer, i) {
16427				nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>';
16428				nSizer.childNodes[0].style.height = "0";
16429				nSizer.childNodes[0].style.overflow = "hidden";
16430				nSizer.style.width = footerWidths[i];
16431			}, footerSrcEls );
16432		}
16433	
16434		// Sanity check that the table is of a sensible width. If not then we are going to get
16435		// misalignment - try to prevent this by not allowing the table to shrink below its min width
16436		if ( table.outerWidth() < sanityWidth
vendor: 29,265 bytes, lines 16436-17442
16436 )
16437		{
16438			// The min width depends upon if we have a vertical scrollbar visible or not */
16439			correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
16440				divBody.css('overflow-y') == "scroll")) ?
16441					sanityWidth+barWidth :
16442					sanityWidth;
16443	
16444			// IE6/7 are a law unto themselves...
16445			if ( ie67 && (divBodyEl.scrollHeight >
16446				divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
16447			) {
16448				tableStyle.width = _fnStringToCss( correction-barWidth );
16449			}
16450	
16451			// And give the user a warning that we've stopped the table getting too small
16452			if ( scrollX === "" || scrollXInner !== "" ) {
16453				_fnLog( settings, 1, 'Possible column misalignment', 6 );
16454			}
16455		}
16456		else
16457		{
16458			correction = '100%';
16459		}
16460	
16461		// Apply to the container elements
16462		divBodyStyle.width = _fnStringToCss( correction );
16463		divHeaderStyle.width = _fnStringToCss( correction );
16464	
16465		if ( footer ) {
16466			settings.nScrollFoot.style.width = _fnStringToCss( correction );
16467		}
16468	
16469	
16470		/*
16471		 * 4. Clean up
16472		 */
16473		if ( ! scrollY ) {
16474			/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
16475			 * the scrollbar height from the visible display, rather than adding it on. We need to
16476			 * set the height in order to sort this. Don't want to do it in any other browsers.
16477			 */
16478			if ( ie67 ) {
16479				divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
16480			}
16481		}
16482	
16483		/* Finally set the width's of the header and footer tables */
16484		var iOuterWidth = table.outerWidth();
16485		divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
16486		divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
16487	
16488		// Figure out if there are scrollbar present - if so then we need a the header and footer to
16489		// provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
16490		var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
16491		var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
16492		divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
16493	
16494		if ( footer ) {
16495			divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
16496			divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
16497			divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
16498		}
16499	
16500		// Correct DOM ordering for colgroup - comes before the thead
16501		table.children('colgroup').insertBefore( table.children('thead') );
16502	
16503		/* Adjust the position of the header in case we loose the y-scrollbar */
16504		divBody.trigger('scroll');
16505	
16506		// If sorting or filtering has occurred, jump the scrolling back to the top
16507		// only if we aren't holding the position
16508		if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
16509			divBodyEl.scrollTop = 0;
16510		}
16511	}
16512	
16513	
16514	
16515	/**
16516	 * Apply a given function to the display child nodes of an element array (typically
16517	 * TD children of TR rows
16518	 *  @param {function} fn Method to apply to the objects
16519	 *  @param array {nodes} an1 List of elements to look through for display children
16520	 *  @param array {nodes} an2 Another list (identical structure to the first) - optional
16521	 *  @memberof DataTable#oApi
16522	 */
16523	function _fnApplyToChildren( fn, an1, an2 )
16524	{
16525		var index=0, i=0, iLen=an1.length;
16526		var nNode1, nNode2;
16527	
16528		while ( i < iLen ) {
16529			nNode1 = an1[i].firstChild;
16530			nNode2 = an2 ? an2[i].firstChild : null;
16531	
16532			while ( nNode1 ) {
16533				if ( nNode1.nodeType === 1 ) {
16534					if ( an2 ) {
16535						fn( nNode1, nNode2, index );
16536					}
16537					else {
16538						fn( nNode1, index );
16539					}
16540	
16541					index++;
16542				}
16543	
16544				nNode1 = nNode1.nextSibling;
16545				nNode2 = an2 ? nNode2.nextSibling : null;
16546			}
16547	
16548			i++;
16549		}
16550	}
16551	
16552	
16553	
16554	var __re_html_remove = /<.*?>/g;
16555	
16556	
16557	/**
16558	 * Calculate the width of columns for the table
16559	 *  @param {object} oSettings dataTables settings object
16560	 *  @memberof DataTable#oApi
16561	 */
16562	function _fnCalculateColumnWidths ( oSettings )
16563	{
16564		var
16565			table = oSettings.nTable,
16566			columns = oSettings.aoColumns,
16567			scroll = oSettings.oScroll,
16568			scrollY = scroll.sY,
16569			scrollX = scroll.sX,
16570			scrollXInner = scroll.sXInner,
16571			columnCount = columns.length,
16572			visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
16573			headerCells = $('th', oSettings.nTHead),
16574			tableWidthAttr = table.getAttribute('width'), // from DOM element
16575			tableContainer = table.parentNode,
16576			userInputs = false,
16577			i, column, columnIdx, width, outerWidth,
16578			browser = oSettings.oBrowser,
16579			ie67 = browser.bScrollOversize;
16580	
16581		var styleWidth = table.style.width;
16582		if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
16583			tableWidthAttr = styleWidth;
16584		}
16585	
16586		/* Convert any user input sizes into pixel sizes */
16587		for ( i=0 ; i<visibleColumns.length ; i++ ) {
16588			column = columns[ visibleColumns[i] ];
16589	
16590			if ( column.sWidth !== null ) {
16591				column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
16592	
16593				userInputs = true;
16594			}
16595		}
16596	
16597		/* If the number of columns in the DOM equals the number that we have to
16598		 * process in DataTables, then we can use the offsets that are created by
16599		 * the web- browser. No custom sizes can be set in order for this to happen,
16600		 * nor scrolling used
16601		 */
16602		if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
16603		     columnCount == _fnVisbleColumns( oSettings ) &&
16604		     columnCount == headerCells.length
16605		) {
16606			for ( i=0 ; i<columnCount ; i++ ) {
16607				var colIdx = _fnVisibleToColumnIndex( oSettings, i );
16608	
16609				if ( colIdx !== null ) {
16610					columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
16611				}
16612			}
16613		}
16614		else
16615		{
16616			// Otherwise construct a single row, worst case, table with the widest
16617			// node in the data, assign any user defined widths, then insert it into
16618			// the DOM and allow the browser to do all the hard work of calculating
16619			// table widths
16620			var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
16621				.css( 'visibility', 'hidden' )
16622				.removeAttr( 'id' );
16623	
16624			// Clean up the table body
16625			tmpTable.find('tbody tr').remove();
16626			var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
16627	
16628			// Clone the table header and footer - we can't use the header / footer
16629			// from the cloned table, since if scrolling is active, the table's
16630			// real header and footer are contained in different table tags
16631			tmpTable.find('thead, tfoot').remove();
16632			tmpTable
16633				.append( $(oSettings.nTHead).clone() )
16634				.append( $(oSettings.nTFoot).clone() );
16635	
16636			// Remove any assigned widths from the footer (from scrolling)
16637			tmpTable.find('tfoot th, tfoot td').css('width', '');
16638	
16639			// Apply custom sizing to the cloned header
16640			headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
16641	
16642			for ( i=0 ; i<visibleColumns.length ; i++ ) {
16643				column = columns[ visibleColumns[i] ];
16644	
16645				headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
16646					_fnStringToCss( column.sWidthOrig ) :
16647					'';
16648	
16649				// For scrollX we need to force the column width otherwise the
16650				// browser will collapse it. If this width is smaller than the
16651				// width the column requires, then it will have no effect
16652				if ( column.sWidthOrig && scrollX ) {
16653					$( headerCells[i] ).append( $('<div/>').css( {
16654						width: column.sWidthOrig,
16655						margin: 0,
16656						padding: 0,
16657						border: 0,
16658						height: 1
16659					} ) );
16660				}
16661			}
16662	
16663			// Find the widest cell for each column and put it into the table
16664			if ( oSettings.aoData.length ) {
16665				for ( i=0 ; i<visibleColumns.length ; i++ ) {
16666					columnIdx = visibleColumns[i];
16667					column = columns[ columnIdx ];
16668	
16669					$( _fnGetWidestNode( oSettings, columnIdx ) )
16670						.clone( false )
16671						.append( column.sContentPadding )
16672						.appendTo( tr );
16673				}
16674			}
16675	
16676			// Tidy the temporary table - remove name attributes so there aren't
16677			// duplicated in the dom (radio elements for example)
16678			$('[name]', tmpTable).removeAttr('name');
16679	
16680			// Table has been built, attach to the document so we can work with it.
16681			// A holding element is used, positioned at the top of the container
16682			// with minimal height, so it has no effect on if the container scrolls
16683			// or not. Otherwise it might trigger scrolling when it actually isn't
16684			// needed
16685			var holder = $('<div/>').css( scrollX || scrollY ?
16686					{
16687						position: 'absolute',
16688						top: 0,
16689						left: 0,
16690						height: 1,
16691						right: 0,
16692						overflow: 'hidden'
16693					} :
16694					{}
16695				)
16696				.append( tmpTable )
16697				.appendTo( tableContainer );
16698	
16699			// When scrolling (X or Y) we want to set the width of the table as 
16700			// appropriate. However, when not scrolling leave the table width as it
16701			// is. This results in slightly different, but I think correct behaviour
16702			if ( scrollX && scrollXInner ) {
16703				tmpTable.width( scrollXInner );
16704			}
16705			else if ( scrollX ) {
16706				tmpTable.css( 'width', 'auto' );
16707				tmpTable.removeAttr('width');
16708	
16709				// If there is no width attribute or style, then allow the table to
16710				// collapse
16711				if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
16712					tmpTable.width( tableContainer.clientWidth );
16713				}
16714			}
16715			else if ( scrollY ) {
16716				tmpTable.width( tableContainer.clientWidth );
16717			}
16718			else if ( tableWidthAttr ) {
16719				tmpTable.width( tableWidthAttr );
16720			}
16721	
16722			// Get the width of each column in the constructed table - we need to
16723			// know the inner width (so it can be assigned to the other table's
16724			// cells) and the outer width so we can calculate the full width of the
16725			// table. This is safe since DataTables requires a unique cell for each
16726			// column, but if ever a header can span multiple columns, this will
16727			// need to be modified.
16728			var total = 0;
16729			for ( i=0 ; i<visibleColumns.length ; i++ ) {
16730				var cell = $(headerCells[i]);
16731				var border = cell.outerWidth() - cell.width();
16732	
16733				// Use getBounding... where possible (not IE8-) because it can give
16734				// sub-pixel accuracy, which we then want to round up!
16735				var bounding = browser.bBounding ?
16736					Math.ceil( headerCells[i].getBoundingClientRect().width ) :
16737					cell.outerWidth();
16738	
16739				// Total is tracked to remove any sub-pixel errors as the outerWidth
16740				// of the table might not equal the total given here (IE!).
16741				total += bounding;
16742	
16743				// Width for each column to use
16744				columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
16745			}
16746	
16747			table.style.width = _fnStringToCss( total );
16748	
16749			// Finished with the table - ditch it
16750			holder.remove();
16751		}
16752	
16753		// If there is a width attr, we want to attach an event listener which
16754		// allows the table sizing to automatically adjust when the window is
16755		// resized. Use the width attr rather than CSS, since we can't know if the
16756		// CSS is a relative value or absolute - DOM read is always px.
16757		if ( tableWidthAttr ) {
16758			table.style.width = _fnStringToCss( tableWidthAttr );
16759		}
16760	
16761		if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
16762			var bindResize = function () {
16763				$(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
16764					_fnAdjustColumnSizing( oSettings );
16765				} ) );
16766			};
16767	
16768			// IE6/7 will crash if we bind a resize event handler on page load.
16769			// To be removed in 1.11 which drops IE6/7 support
16770			if ( ie67 ) {
16771				setTimeout( bindResize, 1000 );
16772			}
16773			else {
16774				bindResize();
16775			}
16776	
16777			oSettings._reszEvt = true;
16778		}
16779	}
16780	
16781	
16782	/**
16783	 * Throttle the calls to a function. Arguments and context are maintained for
16784	 * the throttled function
16785	 *  @param {function} fn Function to be called
16786	 *  @param {int} [freq=200] call frequency in mS
16787	 *  @returns {function} wrapped function
16788	 *  @memberof DataTable#oApi
16789	 */
16790	var _fnThrottle = DataTable.util.throttle;
16791	
16792	
16793	/**
16794	 * Convert a CSS unit width to pixels (e.g. 2em)
16795	 *  @param {string} width width to be converted
16796	 *  @param {node} parent parent to get the with for (required for relative widths) - optional
16797	 *  @returns {int} width in pixels
16798	 *  @memberof DataTable#oApi
16799	 */
16800	function _fnConvertToWidth ( width, parent )
16801	{
16802		if ( ! width ) {
16803			return 0;
16804		}
16805	
16806		var n = $('<div/>')
16807			.css( 'width', _fnStringToCss( width ) )
16808			.appendTo( parent || document.body );
16809	
16810		var val = n[0].offsetWidth;
16811		n.remove();
16812	
16813		return val;
16814	}
16815	
16816	
16817	/**
16818	 * Get the widest node
16819	 *  @param {object} settings dataTables settings object
16820	 *  @param {int} colIdx column of interest
16821	 *  @returns {node} widest table node
16822	 *  @memberof DataTable#oApi
16823	 */
16824	function _fnGetWidestNode( settings, colIdx )
16825	{
16826		var idx = _fnGetMaxLenString( settings, colIdx );
16827		if ( idx < 0 ) {
16828			return null;
16829		}
16830	
16831		var data = settings.aoData[ idx ];
16832		return ! data.nTr ? // Might not have been created when deferred rendering
16833			$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
16834			data.anCells[ colIdx ];
16835	}
16836	
16837	
16838	/**
16839	 * Get the maximum strlen for each data column
16840	 *  @param {object} settings dataTables settings object
16841	 *  @param {int} colIdx column of interest
16842	 *  @returns {string} max string length for each column
16843	 *  @memberof DataTable#oApi
16844	 */
16845	function _fnGetMaxLenString( settings, colIdx )
16846	{
16847		var s, max=-1, maxIdx = -1;
16848	
16849		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
16850			s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
16851			s = s.replace( __re_html_remove, '' );
16852			s = s.replace( /&nbsp;/g, ' ' );
16853	
16854			if ( s.length > max ) {
16855				max = s.length;
16856				maxIdx = i;
16857			}
16858		}
16859	
16860		return maxIdx;
16861	}
16862	
16863	
16864	/**
16865	 * Append a CSS unit (only if required) to a string
16866	 *  @param {string} value to css-ify
16867	 *  @returns {string} value with css unit
16868	 *  @memberof DataTable#oApi
16869	 */
16870	function _fnStringToCss( s )
16871	{
16872		if ( s === null ) {
16873			return '0px';
16874		}
16875	
16876		if ( typeof s == 'number' ) {
16877			return s < 0 ?
16878				'0px' :
16879				s+'px';
16880		}
16881	
16882		// Check it has a unit character already
16883		return s.match(/\d$/) ?
16884			s+'px' :
16885			s;
16886	}
16887	
16888	
16889	
16890	function _fnSortFlatten ( settings )
16891	{
16892		var
16893			i, iLen, k, kLen,
16894			aSort = [],
16895			aiOrig = [],
16896			aoColumns = settings.aoColumns,
16897			aDataSort, iCol, sType, srcCol,
16898			fixed = settings.aaSortingFixed,
16899			fixedObj = $.isPlainObject( fixed ),
16900			nestedSort = [],
16901			add = function ( a ) {
16902				if ( a.length && ! Array.isArray( a[0] ) ) {
16903					// 1D array
16904					nestedSort.push( a );
16905				}
16906				else {
16907					// 2D array
16908					$.merge( nestedSort, a );
16909				}
16910			};
16911	
16912		// Build the sort array, with pre-fix and post-fix options if they have been
16913		// specified
16914		if ( Array.isArray( fixed ) ) {
16915			add( fixed );
16916		}
16917	
16918		if ( fixedObj && fixed.pre ) {
16919			add( fixed.pre );
16920		}
16921	
16922		add( settings.aaSorting );
16923	
16924		if (fixedObj && fixed.post ) {
16925			add( fixed.post );
16926		}
16927	
16928		for ( i=0 ; i<nestedSort.length ; i++ )
16929		{
16930			srcCol = nestedSort[i][0];
16931			aDataSort = aoColumns[ srcCol ].aDataSort;
16932	
16933			for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
16934			{
16935				iCol = aDataSort[k];
16936				sType = aoColumns[ iCol ].sType || 'string';
16937	
16938				if ( nestedSort[i]._idx === undefined ) {
16939					nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
16940				}
16941	
16942				aSort.push( {
16943					src:       srcCol,
16944					col:       iCol,
16945					dir:       nestedSort[i][1],
16946					index:     nestedSort[i]._idx,
16947					type:      sType,
16948					formatter: DataTable.ext.type.order[ sType+"-pre" ]
16949				} );
16950			}
16951		}
16952	
16953		return aSort;
16954	}
16955	
16956	/**
16957	 * Change the order of the table
16958	 *  @param {object} oSettings dataTables settings object
16959	 *  @memberof DataTable#oApi
16960	 *  @todo This really needs split up!
16961	 */
16962	function _fnSort ( oSettings )
16963	{
16964		var
16965			i, ien, iLen, j, jLen, k, kLen,
16966			sDataType, nTh,
16967			aiOrig = [],
16968			oExtSort = DataTable.ext.type.order,
16969			aoData = oSettings.aoData,
16970			aoColumns = oSettings.aoColumns,
16971			aDataSort, data, iCol, sType, oSort,
16972			formatters = 0,
16973			sortCol,
16974			displayMaster = oSettings.aiDisplayMaster,
16975			aSort;
16976	
16977		// Resolve any column types that are unknown due to addition or invalidation
16978		// @todo Can this be moved into a 'data-ready' handler which is called when
16979		//   data is going to be used in the table?
16980		_fnColumnTypes( oSettings );
16981	
16982		aSort = _fnSortFlatten( oSettings );
16983	
16984		for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
16985			sortCol = aSort[i];
16986	
16987			// Track if we can use the fast sort algorithm
16988			if ( sortCol.formatter ) {
16989				formatters++;
16990			}
16991	
16992			// Load the data needed for the sort, for each cell
16993			_fnSortData( oSettings, sortCol.col );
16994		}
16995	
16996		/* No sorting required if server-side or no sorting array */
16997		if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
16998		{
16999			// Create a value - key array of the current row positions such that we can use their
17000			// current position during the sort, if values match, in order to perform stable sorting
17001			for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
17002				aiOrig[ displayMaster[i] ] = i;
17003			}
17004	
17005			/* Do the sort - here we want multi-column sorting based on a given data source (column)
17006			 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
17007			 * follow on it's own, but this is what we want (example two column sorting):
17008			 *  fnLocalSorting = function(a,b){
17009			 *    var iTest;
17010			 *    iTest = oSort['string-asc']('data11', 'data12');
17011			 *      if (iTest !== 0)
17012			 *        return iTest;
17013			 *    iTest = oSort['numeric-desc']('data21', 'data22');
17014			 *    if (iTest !== 0)
17015			 *      return iTest;
17016			 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
17017			 *  }
17018			 * Basically we have a test for each sorting column, if the data in that column is equal,
17019			 * test the next column. If all columns match, then we use a numeric sort on the row
17020			 * positions in the original data array to provide a stable sort.
17021			 *
17022			 * Note - I know it seems excessive to have two sorting methods, but the first is around
17023			 * 15% faster, so the second is only maintained for backwards compatibility with sorting
17024			 * methods which do not have a pre-sort formatting function.
17025			 */
17026			if ( formatters === aSort.length ) {
17027				// All sort types have formatting functions
17028				displayMaster.sort( function ( a, b ) {
17029					var
17030						x, y, k, test, sort,
17031						len=aSort.length,
17032						dataA = aoData[a]._aSortData,
17033						dataB = aoData[b]._aSortData;
17034	
17035					for ( k=0 ; k<len ; k++ ) {
17036						sort = aSort[k];
17037	
17038						x = dataA[ sort.col ];
17039						y = dataB[ sort.col ];
17040	
17041						test = x<y ? -1 : x>y ? 1 : 0;
17042						if ( test !== 0 ) {
17043							return sort.dir === 'asc' ? test : -test;
17044						}
17045					}
17046	
17047					x = aiOrig[a];
17048					y = aiOrig[b];
17049					return x<y ? -1 : x>y ? 1 : 0;
17050				} );
17051			}
17052			else {
17053				// Depreciated - remove in 1.11 (providing a plug-in option)
17054				// Not all sort types have formatting methods, so we have to call their sorting
17055				// methods.
17056				displayMaster.sort( function ( a, b ) {
17057					var
17058						x, y, k, l, test, sort, fn,
17059						len=aSort.length,
17060						dataA = aoData[a]._aSortData,
17061						dataB = aoData[b]._aSortData;
17062	
17063					for ( k=0 ; k<len ; k++ ) {
17064						sort = aSort[k];
17065	
17066						x = dataA[ sort.col ];
17067						y = dataB[ sort.col ];
17068	
17069						fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
17070						test = fn( x, y );
17071						if ( test !== 0 ) {
17072							return test;
17073						}
17074					}
17075	
17076					x = aiOrig[a];
17077					y = aiOrig[b];
17078					return x<y ? -1 : x>y ? 1 : 0;
17079				} );
17080			}
17081		}
17082	
17083		/* Tell the draw function that we have sorted the data */
17084		oSettings.bSorted = true;
17085	}
17086	
17087	
17088	function _fnSortAria ( settings )
17089	{
17090		var label;
17091		var nextSort;
17092		var columns = settings.aoColumns;
17093		var aSort = _fnSortFlatten( settings );
17094		var oAria = settings.oLanguage.oAria;
17095	
17096		// ARIA attributes - need to loop all columns, to update all (removing old
17097		// attributes as needed)
17098		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
17099		{
17100			var col = columns[i];
17101			var asSorting = col.asSorting;
17102			var sTitle = col.ariaTitle || col.sTitle.replace( /<.*?>/g, "" );
17103			var th = col.nTh;
17104	
17105			// IE7 is throwing an error when setting these properties with jQuery's
17106			// attr() and removeAttr() methods...
17107			th.removeAttribute('aria-sort');
17108	
17109			/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
17110			if ( col.bSortable ) {
17111				if ( aSort.length > 0 && aSort[0].col == i ) {
17112					th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
17113					nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
17114				}
17115				else {
17116					nextSort = asSorting[0];
17117				}
17118	
17119				label = sTitle + ( nextSort === "asc" ?
17120					oAria.sSortAscending :
17121					oAria.sSortDescending
17122				);
17123			}
17124			else {
17125				label = sTitle;
17126			}
17127	
17128			th.setAttribute('aria-label', label);
17129		}
17130	}
17131	
17132	
17133	/**
17134	 * Function to run on user sort request
17135	 *  @param {object} settings dataTables settings object
17136	 *  @param {node} attachTo node to attach the handler to
17137	 *  @param {int} colIdx column sorting index
17138	 *  @param {boolean} [append=false] Append the requested sort to the existing
17139	 *    sort if true (i.e. multi-column sort)
17140	 *  @param {function} [callback] callback function
17141	 *  @memberof DataTable#oApi
17142	 */
17143	function _fnSortListener ( settings, colIdx, append, callback )
17144	{
17145		var col = settings.aoColumns[ colIdx ];
17146		var sorting = settings.aaSorting;
17147		var asSorting = col.asSorting;
17148		var nextSortIdx;
17149		var next = function ( a, overflow ) {
17150			var idx = a._idx;
17151			if ( idx === undefined ) {
17152				idx = $.inArray( a[1], asSorting );
17153			}
17154	
17155			return idx+1 < asSorting.length ?
17156				idx+1 :
17157				overflow ?
17158					null :
17159					0;
17160		};
17161	
17162		// Convert to 2D array if needed
17163		if ( typeof sorting[0] === 'number' ) {
17164			sorting = settings.aaSorting = [ sorting ];
17165		}
17166	
17167		// If appending the sort then we are multi-column sorting
17168		if ( append && settings.oFeatures.bSortMulti ) {
17169			// Are we already doing some kind of sort on this column?
17170			var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
17171	
17172			if ( sortIdx !== -1 ) {
17173				// Yes, modify the sort
17174				nextSortIdx = next( sorting[sortIdx], true );
17175	
17176				if ( nextSortIdx === null && sorting.length === 1 ) {
17177					nextSortIdx = 0; // can't remove sorting completely
17178				}
17179	
17180				if ( nextSortIdx === null ) {
17181					sorting.splice( sortIdx, 1 );
17182				}
17183				else {
17184					sorting[sortIdx][1] = asSorting[ nextSortIdx ];
17185					sorting[sortIdx]._idx = nextSortIdx;
17186				}
17187			}
17188			else {
17189				// No sort on this column yet
17190				sorting.push( [ colIdx, asSorting[0], 0 ] );
17191				sorting[sorting.length-1]._idx = 0;
17192			}
17193		}
17194		else if ( sorting.length && sorting[0][0] == colIdx ) {
17195			// Single column - already sorting on this column, modify the sort
17196			nextSortIdx = next( sorting[0] );
17197	
17198			sorting.length = 1;
17199			sorting[0][1] = asSorting[ nextSortIdx ];
17200			sorting[0]._idx = nextSortIdx;
17201		}
17202		else {
17203			// Single column - sort only on this column
17204			sorting.length = 0;
17205			sorting.push( [ colIdx, asSorting[0] ] );
17206			sorting[0]._idx = 0;
17207		}
17208	
17209		// Run the sort by calling a full redraw
17210		_fnReDraw( settings );
17211	
17212		// callback used for async user interaction
17213		if ( typeof callback == 'function' ) {
17214			callback( settings );
17215		}
17216	}
17217	
17218	
17219	/**
17220	 * Attach a sort handler (click) to a node
17221	 *  @param {object} settings dataTables settings object
17222	 *  @param {node} attachTo node to attach the handler to
17223	 *  @param {int} colIdx column sorting index
17224	 *  @param {function} [callback] callback function
17225	 *  @memberof DataTable#oApi
17226	 */
17227	function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
17228	{
17229		var col = settings.aoColumns[ colIdx ];
17230	
17231		_fnBindAction( attachTo, {}, function (e) {
17232			/* If the column is not sortable - don't to anything */
17233			if ( col.bSortable === false ) {
17234				return;
17235			}
17236	
17237			// If processing is enabled use a timeout to allow the processing
17238			// display to be shown - otherwise to it synchronously
17239			if ( settings.oFeatures.bProcessing ) {
17240				_fnProcessingDisplay( settings, true );
17241	
17242				setTimeout( function() {
17243					_fnSortListener( settings, colIdx, e.shiftKey, callback );
17244	
17245					// In server-side processing, the draw callback will remove the
17246					// processing display
17247					if ( _fnDataSource( settings ) !== 'ssp' ) {
17248						_fnProcessingDisplay( settings, false );
17249					}
17250				}, 0 );
17251			}
17252			else {
17253				_fnSortListener( settings, colIdx, e.shiftKey, callback );
17254			}
17255		} );
17256	}
17257	
17258	
17259	/**
17260	 * Set the sorting classes on table's body, Note: it is safe to call this function
17261	 * when bSort and bSortClasses are false
17262	 *  @param {object} oSettings dataTables settings object
17263	 *  @memberof DataTable#oApi
17264	 */
17265	function _fnSortingClasses( settings )
17266	{
17267		var oldSort = settings.aLastSort;
17268		var sortClass = settings.oClasses.sSortColumn;
17269		var sort = _fnSortFlatten( settings );
17270		var features = settings.oFeatures;
17271		var i, ien, colIdx;
17272	
17273		if ( features.bSort && features.bSortClasses ) {
17274			// Remove old sorting classes
17275			for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
17276				colIdx = oldSort[i].src;
17277	
17278				// Remove column sorting
17279				$( _pluck( settings.aoData, 'anCells', colIdx ) )
17280					.removeClass( sortClass + (i<2 ? i+1 : 3) );
17281			}
17282	
17283			// Add new column sorting
17284			for ( i=0, ien=sort.length ; i<ien ; i++ ) {
17285				colIdx = sort[i].src;
17286	
17287				$( _pluck( settings.aoData, 'anCells', colIdx ) )
17288					.addClass( sortClass + (i<2 ? i+1 : 3) );
17289			}
17290		}
17291	
17292		settings.aLastSort = sort;
17293	}
17294	
17295	
17296	// Get the data to sort a column, be it from cache, fresh (populating the
17297	// cache), or from a sort formatter
17298	function _fnSortData( settings, idx )
17299	{
17300		// Custom sorting function - provided by the sort data type
17301		var column = settings.aoColumns[ idx ];
17302		var customSort = DataTable.ext.order[ column.sSortDataType ];
17303		var customData;
17304	
17305		if ( customSort ) {
17306			customData = customSort.call( settings.oInstance, settings, idx,
17307				_fnColumnIndexToVisible( settings, idx )
17308			);
17309		}
17310	
17311		// Use / populate cache
17312		var row, cellData;
17313		var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
17314	
17315		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
17316			row = settings.aoData[i];
17317	
17318			if ( ! row._aSortData ) {
17319				row._aSortData = [];
17320			}
17321	
17322			if ( ! row._aSortData[idx] || customSort ) {
17323				cellData = customSort ?
17324					customData[i] : // If there was a custom sort function, use data from there
17325					_fnGetCellData( settings, i, idx, 'sort' );
17326	
17327				row._aSortData[ idx ] = formatter ?
17328					formatter( cellData ) :
17329					cellData;
17330			}
17331		}
17332	}
17333	
17334	
17335	
17336	/**
17337	 * Save the state of a table
17338	 *  @param {object} oSettings dataTables settings object
17339	 *  @memberof DataTable#oApi
17340	 */
17341	function _fnSaveState ( settings )
17342	{
17343		if (settings._bLoadingState) {
17344			return;
17345		}
17346	
17347		/* Store the interesting variables */
17348		var state = {
17349			time:    +new Date(),
17350			start:   settings._iDisplayStart,
17351			length:  settings._iDisplayLength,
17352			order:   $.extend( true, [], settings.aaSorting ),
17353			search:  _fnSearchToCamel( settings.oPreviousSearch ),
17354			columns: $.map( settings.aoColumns, function ( col, i ) {
17355				return {
17356					visible: col.bVisible,
17357					search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
17358				};
17359			} )
17360		};
17361	
17362		settings.oSavedState = state;
17363		_fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
17364		
17365		if ( settings.oFeatures.bStateSave && !settings.bDestroying )
17366		{
17367			settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
17368		}	
17369	}
17370	
17371	
17372	/**
17373	 * Attempt to load a saved table state
17374	 *  @param {object} oSettings dataTables settings object
17375	 *  @param {object} oInit DataTables init object so we can override settings
17376	 *  @param {function} callback Callback to execute when the state has been loaded
17377	 *  @memberof DataTable#oApi
17378	 */
17379	function _fnLoadState ( settings, oInit, callback )
17380	{
17381		if ( ! settings.oFeatures.bStateSave ) {
17382			callback();
17383			return;
17384		}
17385	
17386		var loaded = function(state) {
17387			_fnImplementState(settings, state, callback);
17388		}
17389	
17390		var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
17391	
17392		if ( state !== undefined ) {
17393			_fnImplementState( settings, state, callback );
17394		}
17395		// otherwise, wait for the loaded callback to be executed
17396	
17397		return true;
17398	}
17399	
17400	function _fnImplementState ( settings, s, callback) {
17401		var i, ien;
17402		var columns = settings.aoColumns;
17403		settings._bLoadingState = true;
17404	
17405		// When StateRestore was introduced the state could now be implemented at any time
17406		// Not just initialisation. To do this an api instance is required in some places
17407		var api = settings._bInitComplete ? new DataTable.Api(settings) : null;
17408	
17409		if ( ! s || ! s.time ) {
17410			settings._bLoadingState = false;
17411			callback();
17412			return;
17413		}
17414	
17415		// Allow custom and plug-in manipulation functions to alter the saved data set and
17416		// cancelling of loading by returning false
17417		var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );
17418		if ( $.inArray( false, abStateLoad ) !== -1 ) {
17419			settings._bLoadingState = false;
17420			callback();
17421			return;
17422		}
17423	
17424		// Reject old data
17425		var duration = settings.iStateDuration;
17426		if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
17427			settings._bLoadingState = false;
17428			callback();
17429			return;
17430		}
17431	
17432		// Number of columns have changed - all bets are off, no restore of settings
17433		if ( s.columns && columns.length !== s.columns.length ) {
17434			settings._bLoadingState = false;
17435			callback();
17436			return;
17437		}
17438	
17439		// Store the saved state so it might be accessed at any time
17440		settings.oLoadedState = $.extend( true, {}, s );
17441	
17442		// 
vendor: 13,462 bytes, lines 17442-17918
17442Restore key features - todo - for 1.11 this needs to be done by
17443		// subscribed events
17444		if ( s.start !== undefined ) {
17445			settings._iDisplayStart    = s.start;
17446			if(api === null) {
17447				settings.iInitDisplayStart = s.start;
17448			}
17449		}
17450		if ( s.length !== undefined ) {
17451			settings._iDisplayLength   = s.length;
17452		}
17453	
17454		// Order
17455		if ( s.order !== undefined ) {
17456			settings.aaSorting = [];
17457			$.each( s.order, function ( i, col ) {
17458				settings.aaSorting.push( col[0] >= columns.length ?
17459					[ 0, col[1] ] :
17460					col
17461				);
17462			} );
17463		}
17464	
17465		// Search
17466		if ( s.search !== undefined ) {
17467			$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
17468		}
17469	
17470		// Columns
17471		if ( s.columns ) {
17472			for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
17473				var col = s.columns[i];
17474	
17475				// Visibility
17476				if ( col.visible !== undefined ) {
17477					// If the api is defined, the table has been initialised so we need to use it rather than internal settings
17478					if (api) {
17479						// Don't redraw the columns on every iteration of this loop, we will do this at the end instead
17480						api.column(i).visible(col.visible, false);
17481					}
17482					else {
17483						columns[i].bVisible = col.visible;
17484					}
17485				}
17486	
17487				// Search
17488				if ( col.search !== undefined ) {
17489					$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
17490				}
17491			}
17492			
17493			// If the api is defined then we need to adjust the columns once the visibility has been changed
17494			if (api) {
17495				api.columns.adjust();
17496			}
17497		}
17498	
17499		settings._bLoadingState = false;
17500		_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );
17501		callback();
17502	};
17503	
17504	
17505	/**
17506	 * Return the settings object for a particular table
17507	 *  @param {node} table table we are using as a dataTable
17508	 *  @returns {object} Settings object - or null if not found
17509	 *  @memberof DataTable#oApi
17510	 */
17511	function _fnSettingsFromNode ( table )
17512	{
17513		var settings = DataTable.settings;
17514		var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
17515	
17516		return idx !== -1 ?
17517			settings[ idx ] :
17518			null;
17519	}
17520	
17521	
17522	/**
17523	 * Log an error message
17524	 *  @param {object} settings dataTables settings object
17525	 *  @param {int} level log error messages, or display them to the user
17526	 *  @param {string} msg error message
17527	 *  @param {int} tn Technical note id to get more information about the error.
17528	 *  @memberof DataTable#oApi
17529	 */
17530	function _fnLog( settings, level, msg, tn )
17531	{
17532		msg = 'DataTables warning: '+
17533			(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
17534	
17535		if ( tn ) {
17536			msg += '. For more information about this error, please see '+
17537			'http://datatables.net/tn/'+tn;
17538		}
17539	
17540		if ( ! level  ) {
17541			// Backwards compatibility pre 1.10
17542			var ext = DataTable.ext;
17543			var type = ext.sErrMode || ext.errMode;
17544	
17545			if ( settings ) {
17546				_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
17547			}
17548	
17549			if ( type == 'alert' ) {
17550				alert( msg );
17551			}
17552			else if ( type == 'throw' ) {
17553				throw new Error(msg);
17554			}
17555			else if ( typeof type == 'function' ) {
17556				type( settings, tn, msg );
17557			}
17558		}
17559		else if ( window.console && console.log ) {
17560			console.log( msg );
17561		}
17562	}
17563	
17564	
17565	/**
17566	 * See if a property is defined on one object, if so assign it to the other object
17567	 *  @param {object} ret target object
17568	 *  @param {object} src source object
17569	 *  @param {string} name property
17570	 *  @param {string} [mappedName] name to map too - optional, name used if not given
17571	 *  @memberof DataTable#oApi
17572	 */
17573	function _fnMap( ret, src, name, mappedName )
17574	{
17575		if ( Array.isArray( name ) ) {
17576			$.each( name, function (i, val) {
17577				if ( Array.isArray( val ) ) {
17578					_fnMap( ret, src, val[0], val[1] );
17579				}
17580				else {
17581					_fnMap( ret, src, val );
17582				}
17583			} );
17584	
17585			return;
17586		}
17587	
17588		if ( mappedName === undefined ) {
17589			mappedName = name;
17590		}
17591	
17592		if ( src[name] !== undefined ) {
17593			ret[mappedName] = src[name];
17594		}
17595	}
17596	
17597	
17598	/**
17599	 * Extend objects - very similar to jQuery.extend, but deep copy objects, and
17600	 * shallow copy arrays. The reason we need to do this, is that we don't want to
17601	 * deep copy array init values (such as aaSorting) since the dev wouldn't be
17602	 * able to override them, but we do want to deep copy arrays.
17603	 *  @param {object} out Object to extend
17604	 *  @param {object} extender Object from which the properties will be applied to
17605	 *      out
17606	 *  @param {boolean} breakRefs If true, then arrays will be sliced to take an
17607	 *      independent copy with the exception of the `data` or `aaData` parameters
17608	 *      if they are present. This is so you can pass in a collection to
17609	 *      DataTables and have that used as your data source without breaking the
17610	 *      references
17611	 *  @returns {object} out Reference, just for convenience - out === the return.
17612	 *  @memberof DataTable#oApi
17613	 *  @todo This doesn't take account of arrays inside the deep copied objects.
17614	 */
17615	function _fnExtend( out, extender, breakRefs )
17616	{
17617		var val;
17618	
17619		for ( var prop in extender ) {
17620			if ( extender.hasOwnProperty(prop) ) {
17621				val = extender[prop];
17622	
17623				if ( $.isPlainObject( val ) ) {
17624					if ( ! $.isPlainObject( out[prop] ) ) {
17625						out[prop] = {};
17626					}
17627					$.extend( true, out[prop], val );
17628				}
17629				else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && Array.isArray(val) ) {
17630					out[prop] = val.slice();
17631				}
17632				else {
17633					out[prop] = val;
17634				}
17635			}
17636		}
17637	
17638		return out;
17639	}
17640	
17641	
17642	/**
17643	 * Bind an event handers to allow a click or return key to activate the callback.
17644	 * This is good for accessibility since a return on the keyboard will have the
17645	 * same effect as a click, if the element has focus.
17646	 *  @param {element} n Element to bind the action to
17647	 *  @param {object} oData Data object to pass to the triggered function
17648	 *  @param {function} fn Callback function for when the event is triggered
17649	 *  @memberof DataTable#oApi
17650	 */
17651	function _fnBindAction( n, oData, fn )
17652	{
17653		$(n)
17654			.on( 'click.DT', oData, function (e) {
17655					$(n).trigger('blur'); // Remove focus outline for mouse users
17656					fn(e);
17657				} )
17658			.on( 'keypress.DT', oData, function (e){
17659					if ( e.which === 13 ) {
17660						e.preventDefault();
17661						fn(e);
17662					}
17663				} )
17664			.on( 'selectstart.DT', function () {
17665					/* Take the brutal approach to cancelling text selection */
17666					return false;
17667				} );
17668	}
17669	
17670	
17671	/**
17672	 * Register a callback function. Easily allows a callback function to be added to
17673	 * an array store of callback functions that can then all be called together.
17674	 *  @param {object} oSettings dataTables settings object
17675	 *  @param {string} sStore Name of the array storage for the callbacks in oSettings
17676	 *  @param {function} fn Function to be called back
17677	 *  @param {string} sName Identifying name for the callback (i.e. a label)
17678	 *  @memberof DataTable#oApi
17679	 */
17680	function _fnCallbackReg( oSettings, sStore, fn, sName )
17681	{
17682		if ( fn )
17683		{
17684			oSettings[sStore].push( {
17685				"fn": fn,
17686				"sName": sName
17687			} );
17688		}
17689	}
17690	
17691	
17692	/**
17693	 * Fire callback functions and trigger events. Note that the loop over the
17694	 * callback array store is done backwards! Further note that you do not want to
17695	 * fire off triggers in time sensitive applications (for example cell creation)
17696	 * as its slow.
17697	 *  @param {object} settings dataTables settings object
17698	 *  @param {string} callbackArr Name of the array storage for the callbacks in
17699	 *      oSettings
17700	 *  @param {string} eventName Name of the jQuery custom event to trigger. If
17701	 *      null no trigger is fired
17702	 *  @param {array} args Array of arguments to pass to the callback function /
17703	 *      trigger
17704	 *  @memberof DataTable#oApi
17705	 */
17706	function _fnCallbackFire( settings, callbackArr, eventName, args )
17707	{
17708		var ret = [];
17709	
17710		if ( callbackArr ) {
17711			ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
17712				return val.fn.apply( settings.oInstance, args );
17713			} );
17714		}
17715	
17716		if ( eventName !== null ) {
17717			var e = $.Event( eventName+'.dt' );
17718	
17719			$(settings.nTable).trigger( e, args );
17720	
17721			ret.push( e.result );
17722		}
17723	
17724		return ret;
17725	}
17726	
17727	
17728	function _fnLengthOverflow ( settings )
17729	{
17730		var
17731			start = settings._iDisplayStart,
17732			end = settings.fnDisplayEnd(),
17733			len = settings._iDisplayLength;
17734	
17735		/* If we have space to show extra rows (backing up from the end point - then do so */
17736		if ( start >= end )
17737		{
17738			start = end - len;
17739		}
17740	
17741		// Keep the start record on the current page
17742		start -= (start % len);
17743	
17744		if ( len === -1 || start < 0 )
17745		{
17746			start = 0;
17747		}
17748	
17749		settings._iDisplayStart = start;
17750	}
17751	
17752	
17753	function _fnRenderer( settings, type )
17754	{
17755		var renderer = settings.renderer;
17756		var host = DataTable.ext.renderer[type];
17757	
17758		if ( $.isPlainObject( renderer ) && renderer[type] ) {
17759			// Specific renderer for this type. If available use it, otherwise use
17760			// the default.
17761			return host[renderer[type]] || host._;
17762		}
17763		else if ( typeof renderer === 'string' ) {
17764			// Common renderer - if there is one available for this type use it,
17765			// otherwise use the default
17766			return host[renderer] || host._;
17767		}
17768	
17769		// Use the default
17770		return host._;
17771	}
17772	
17773	
17774	/**
17775	 * Detect the data source being used for the table. Used to simplify the code
17776	 * a little (ajax) and to make it compress a little smaller.
17777	 *
17778	 *  @param {object} settings dataTables settings object
17779	 *  @returns {string} Data source
17780	 *  @memberof DataTable#oApi
17781	 */
17782	function _fnDataSource ( settings )
17783	{
17784		if ( settings.oFeatures.bServerSide ) {
17785			return 'ssp';
17786		}
17787		else if ( settings.ajax || settings.sAjaxSource ) {
17788			return 'ajax';
17789		}
17790		return 'dom';
17791	}
17792	
17793
17794	
17795	
17796	/**
17797	 * Computed structure of the DataTables API, defined by the options passed to
17798	 * `DataTable.Api.register()` when building the API.
17799	 *
17800	 * The structure is built in order to speed creation and extension of the Api
17801	 * objects since the extensions are effectively pre-parsed.
17802	 *
17803	 * The array is an array of objects with the following structure, where this
17804	 * base array represents the Api prototype base:
17805	 *
17806	 *     [
17807	 *       {
17808	 *         name:      'data'                -- string   - Property name
17809	 *         val:       function () {},       -- function - Api method (or undefined if just an object
17810	 *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
17811	 *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
17812	 *       },
17813	 *       {
17814	 *         name:     'row'
17815	 *         val:       {},
17816	 *         methodExt: [ ... ],
17817	 *         propExt:   [
17818	 *           {
17819	 *             name:      'data'
17820	 *             val:       function () {},
17821	 *             methodExt: [ ... ],
17822	 *             propExt:   [ ... ]
17823	 *           },
17824	 *           ...
17825	 *         ]
17826	 *       }
17827	 *     ]
17828	 *
17829	 * @type {Array}
17830	 * @ignore
17831	 */
17832	var __apiStruct = [];
17833	
17834	
17835	/**
17836	 * `Array.prototype` reference.
17837	 *
17838	 * @type object
17839	 * @ignore
17840	 */
17841	var __arrayProto = Array.prototype;
17842	
17843	
17844	/**
17845	 * Abstraction for `context` parameter of the `Api` constructor to allow it to
17846	 * take several different forms for ease of use.
17847	 *
17848	 * Each of the input parameter types will be converted to a DataTables settings
17849	 * object where possible.
17850	 *
17851	 * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one
17852	 *   of:
17853	 *
17854	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
17855	 *     with be found and used.
17856	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
17857	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
17858	 *   * `object` - DataTables settings object
17859	 *   * `DataTables.Api` - API instance
17860	 * @return {array|null} Matching DataTables settings objects. `null` or
17861	 *   `undefined` is returned if no matching DataTable is found.
17862	 * @ignore
17863	 */
17864	var _toSettings = function ( mixed )
17865	{
17866		var idx, jq;
17867		var settings = DataTable.settings;
17868		var tables = $.map( settings, function (el, i) {
17869			return el.nTable;
17870		} );
17871	
17872		if ( ! mixed ) {
17873			return [];
17874		}
17875		else if ( mixed.nTable && mixed.oApi ) {
17876			// DataTables settings object
17877			return [ mixed ];
17878		}
17879		else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
17880			// Table node
17881			idx = $.inArray( mixed, tables );
17882			return idx !== -1 ? [ settings[idx] ] : null;
17883		}
17884		else if ( mixed && typeof mixed.settings === 'function' ) {
17885			return mixed.settings().toArray();
17886		}
17887		else if ( typeof mixed === 'string' ) {
17888			// jQuery selector
17889			jq = $(mixed);
17890		}
17891		else if ( mixed instanceof $ ) {
17892			// jQuery object (also DataTables instance)
17893			jq = mixed;
17894		}
17895	
17896		if ( jq ) {
17897			return jq.map( function(i) {
17898				idx = $.inArray( this, tables );
17899				return idx !== -1 ? settings[idx] : null;
17900			} ).toArray();
17901		}
17902	};
17903	
17904	
17905	/**
17906	 * DataTables API class - used to control and interface with  one or more
17907	 * DataTables enhanced tables.
17908	 *
17909	 * The API class is heavily based on jQuery, presenting a chainable interface
17910	 * that you can use to interact with tables. Each instance of the API class has
17911	 * a "context" - i.e. the tables that it will operate on. This could be a single
17912	 * table, all tables on a page or a sub-set thereof.
17913	 *
17914	 * Additionally the API is designed to allow you to easily work with the data in
17915	 * the tables, retrieving and manipulating it as required. This is done by
17916	 * presenting the API class as an array like interface. The contents of the
17917	 * array depend upon the actions requested by each method (for example
17918	 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
17919	 * return an array of objects or arrays depending upon your table's
17920	 * configuration). The API object has a number of array like methods (`push`,
17921	 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
17922	 * `unique` etc) to assist your working with the data held in a table.
17923	 *
17924	 * Most methods (those which return an Api instance) are chainable, which means
17925	 * the return from a method call also has all of the methods available that the
17926	 * top level object had. For example, these two calls are equivalent:
17927	 *
17928	 *     // Not chained
17929	 *     api.row.add( {...} );
17930	 *     api.draw();
17931	 *
17932	 *     // Chained
17933	 *     api.row.add( {...} ).draw();
17934	 *
17935	 * @class DataTable.Api
17936	 * @param {array|object|string|jQuery} context DataTable identifier. This is
17937	 *   used to define which DataTables enhanced tables this API will operate on.
17938	 *   Can be one of:
17939	 *
17940	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
17941	 *     with be found and used.
17942	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
17943	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
17944	 *   * `object` - DataTables settings object
17945	 * @param {array} [data] Data to initialise the Api instance with.
17946	 *
17947	 * @example
17948	 *   // Direct initialisation during DataTables construction
17949	 *   var api = $('#example').DataTable();
17950	 *
17951	 * @example
17952	 *   // Initialisation using a DataTables jQuery object
17953	 *   var api = $('#example').dataTable().api();
17954	 *
17955	 * @example
17956	 *   // Initialisation as a constructor
17957	 *   var api = new $.fn.DataTable.Api( 'table.dataTable' );
17958	 */
17959	_Api = function ( context, data )
17960	{
17961		if ( ! (this instanceof _Api) ) {
17962			return new _Api( context, data );
17963		}
17964	
17965		var settings = [];
17966		var ctxSettings = function ( o ) {
17967			var a = _toSettings( o );
17968			if ( a ) {
17969				settings.push.apply( settings, a );
17970			}
17971		};
17972	
17973		if ( Array.isArray( context ) ) {
17974			for ( var i=0, ien=context.length ; i<ien ; i++ ) {
17975				ctxSettings( context[i] );
17976			}
17977		}
17978		else {
17979			ctxSettings( context );
17980		}
17981	
17982		// Remove duplicates
17983		this.context = _unique( settings );
17984	
17985		// Initial data
17986		if ( data ) {
17987			$.merge( this, data );
17988		}
17989	
17990		// selector
17991		this.selector = {
17992			rows: null,
17993			cols: null,
17994			opts: null
17995		};
17996	
17997		_Api.extend( this, this, __apiStruct );
17998	};
17999	
18000	DataTable.Api = _Api;
18001	
18002	// Don't destroy the existing prototype, just extend it. Required for jQuery 2's
18003	// isPlainObject.
18004	$.extend( _Api.prototype, {
18005		any: function ()
18006		{
18007			return this.count() !== 0;
18008		},
18009	
18010	
18011		concat:  __arrayProto.concat,
18012	
18013	
18014		context: [], // array of table settings objects
18015	
18016	
18017		count: function ()
18018		{
18019			return this.flatten().length;
18020		},
18021	
18022	
18023		each: function ( fn )
18024		{
18025			for ( var i=0, ien=this.length ; i<ien; i++ ) {
18026				fn.call( this, this[i], i, this );
18027			}
18028	
18029			return this;
18030		},
18031	
18032	
18033		eq: function ( idx )
18034		{
18035			var ctx = this.context;
18036	
18037			return ctx.length > idx ?
18038				new _Api( ctx[idx], this[idx] ) :
18039				null;
18040		},
18041	
18042	
18043		filter: function ( fn )
18044		{
18045			var a = [];
18046	
18047			if ( __arrayProto.filter ) {
18048				a = __arrayProto.filter.call( this, fn, this );
18049			}
18050			else {
18051				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
18052				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
18053					if ( fn.call( this, this[i], i, this ) ) {
18054						a.push( this[i] );
18055					}
18056				}
18057			}
18058	
18059			return new _Api( this.context, a );
18060		},
18061	
18062	
18063		flatten: function ()
18064		{
18065			var a = [];
18066			return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
18067		},
18068	
18069	
18070		join:    __arrayProto.join,
18071	
18072	
18073		indexOf: __arrayProto.indexOf || function (obj, start)
18074		{
18075			for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
18076				if ( this[i] === obj ) {
18077					return i;
18078				}
18079			}
18080			return -1;
18081		},
18082	
18083		iterator: function ( flatten, type, fn, alwaysNew ) {
18084			var
18085				a = [], ret,
18086				i, ien, j, jen,
18087				context = this.context,
18088				rows, items, item,
18089				selector = this.selector;
18090	
18091			// Argument shifting
18092			if ( typeof flatten === 'string' ) {
18093				alwaysNew = fn;
18094				fn = type;
18095				type = flatten;
18096				flatten = false;
18097			}
18098	
18099			for ( i=0, ien=context.length ; i<ien ; i++ ) {
18100				var apiInst = new _Api( context[i] );
18101	
18102				if ( type === 'table' ) {
18103					ret = fn.call( apiInst, context[i], i );
18104	
18105					if ( ret !== undefined ) {
18106						a.push( ret );
18107					}
18108				}
18109				else if ( type === 'columns' || type === 'rows' ) {
18110					// this has same length as context - one entry for each table
18111					ret = fn.call( apiInst, context[i], this[i], i );
18112	
18113					if ( ret !== undefined ) {
18114						a.push( ret );
18115					}
18116				}
18117				else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
18118					// columns and rows share the same structure.
18119					// 'this' is an array of column indexes for each context
18120					items = this[i];
18121	
18122					if ( type === 'column-rows' ) {
18123						rows = _selector_row_indexes( context[i], selector.opts );
18124					}
18125	
18126					for ( j=0, jen=items.length ; j<jen ; j++ ) {
18127						item = items[j];
18128	
18129						if ( type === 'cell' ) {
18130							ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
18131						}
18132						else {
18133							ret = fn.call( apiInst, context[i], item, i, j, rows );
18134						}
18135	
18136						if ( ret !== undefined ) {
18137							a.push( ret );
18138						}
18139					}
18140				}
18141			}
18142	
18143			if ( a.length || alwaysNew ) {
18144				var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
18145				var apiSelector = api.selector;
18146				apiSelector.rows = selector.rows;
18147				apiSelector.cols = selector.cols;
18148				apiSelector.opts = selector.opts;
18149				return api;
18150			}
18151			return this;
18152		},
18153	
18154	
18155		lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
18156		{
18157			// Bit cheeky...
18158			return this.indexOf.apply( this.toArray.reverse(), arguments );
18159		},
18160	
18161	
18162		length:  0,
18163	
18164	
18165		map: function ( fn )
18166		{
18167			var a = [];
18168	
18169			if ( __arrayProto.map ) {
18170				a = __arrayProto.map.call( this, fn, this );
18171			}
18172			else {
18173				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
18174				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
18175					a.push( fn.call( this, this[i], i ) );
18176				}
18177			}
18178	
18179			return new _Api( this.context, a );
18180		},
18181	
18182	
18183		pluck: function ( prop )
18184		{
18185			return this.map( function ( el ) {
18186				return el[ prop ]
vendor: 28,402 bytes, lines 18186-19280
18186;
18187			} );
18188		},
18189	
18190		pop:     __arrayProto.pop,
18191	
18192	
18193		push:    __arrayProto.push,
18194	
18195	
18196		// Does not return an API instance
18197		reduce: __arrayProto.reduce || function ( fn, init )
18198		{
18199			return _fnReduce( this, fn, init, 0, this.length, 1 );
18200		},
18201	
18202	
18203		reduceRight: __arrayProto.reduceRight || function ( fn, init )
18204		{
18205			return _fnReduce( this, fn, init, this.length-1, -1, -1 );
18206		},
18207	
18208	
18209		reverse: __arrayProto.reverse,
18210	
18211	
18212		// Object with rows, columns and opts
18213		selector: null,
18214	
18215	
18216		shift:   __arrayProto.shift,
18217	
18218	
18219		slice: function () {
18220			return new _Api( this.context, this );
18221		},
18222	
18223	
18224		sort:    __arrayProto.sort, // ? name - order?
18225	
18226	
18227		splice:  __arrayProto.splice,
18228	
18229	
18230		toArray: function ()
18231		{
18232			return __arrayProto.slice.call( this );
18233		},
18234	
18235	
18236		to$: function ()
18237		{
18238			return $( this );
18239		},
18240	
18241	
18242		toJQuery: function ()
18243		{
18244			return $( this );
18245		},
18246	
18247	
18248		unique: function ()
18249		{
18250			return new _Api( this.context, _unique(this) );
18251		},
18252	
18253	
18254		unshift: __arrayProto.unshift
18255	} );
18256	
18257	
18258	_Api.extend = function ( scope, obj, ext )
18259	{
18260		// Only extend API instances and static properties of the API
18261		if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
18262			return;
18263		}
18264	
18265		var
18266			i, ien,
18267			struct,
18268			methodScoping = function ( scope, fn, struc ) {
18269				return function () {
18270					var ret = fn.apply( scope, arguments );
18271	
18272					// Method extension
18273					_Api.extend( ret, ret, struc.methodExt );
18274					return ret;
18275				};
18276			};
18277	
18278		for ( i=0, ien=ext.length ; i<ien ; i++ ) {
18279			struct = ext[i];
18280	
18281			// Value
18282			obj[ struct.name ] = struct.type === 'function' ?
18283				methodScoping( scope, struct.val, struct ) :
18284				struct.type === 'object' ?
18285					{} :
18286					struct.val;
18287	
18288			obj[ struct.name ].__dt_wrapper = true;
18289	
18290			// Property extension
18291			_Api.extend( scope, obj[ struct.name ], struct.propExt );
18292		}
18293	};
18294	
18295	
18296	// @todo - Is there need for an augment function?
18297	// _Api.augment = function ( inst, name )
18298	// {
18299	// 	// Find src object in the structure from the name
18300	// 	var parts = name.split('.');
18301	
18302	// 	_Api.extend( inst, obj );
18303	// };
18304	
18305	
18306	//     [
18307	//       {
18308	//         name:      'data'                -- string   - Property name
18309	//         val:       function () {},       -- function - Api method (or undefined if just an object
18310	//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
18311	//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
18312	//       },
18313	//       {
18314	//         name:     'row'
18315	//         val:       {},
18316	//         methodExt: [ ... ],
18317	//         propExt:   [
18318	//           {
18319	//             name:      'data'
18320	//             val:       function () {},
18321	//             methodExt: [ ... ],
18322	//             propExt:   [ ... ]
18323	//           },
18324	//           ...
18325	//         ]
18326	//       }
18327	//     ]
18328	
18329	_Api.register = _api_register = function ( name, val )
18330	{
18331		if ( Array.isArray( name ) ) {
18332			for ( var j=0, jen=name.length ; j<jen ; j++ ) {
18333				_Api.register( name[j], val );
18334			}
18335			return;
18336		}
18337	
18338		var
18339			i, ien,
18340			heir = name.split('.'),
18341			struct = __apiStruct,
18342			key, method;
18343	
18344		var find = function ( src, name ) {
18345			for ( var i=0, ien=src.length ; i<ien ; i++ ) {
18346				if ( src[i].name === name ) {
18347					return src[i];
18348				}
18349			}
18350			return null;
18351		};
18352	
18353		for ( i=0, ien=heir.length ; i<ien ; i++ ) {
18354			method = heir[i].indexOf('()') !== -1;
18355			key = method ?
18356				heir[i].replace('()', '') :
18357				heir[i];
18358	
18359			var src = find( struct, key );
18360			if ( ! src ) {
18361				src = {
18362					name:      key,
18363					val:       {},
18364					methodExt: [],
18365					propExt:   [],
18366					type:      'object'
18367				};
18368				struct.push( src );
18369			}
18370	
18371			if ( i === ien-1 ) {
18372				src.val = val;
18373				src.type = typeof val === 'function' ?
18374					'function' :
18375					$.isPlainObject( val ) ?
18376						'object' :
18377						'other';
18378			}
18379			else {
18380				struct = method ?
18381					src.methodExt :
18382					src.propExt;
18383			}
18384		}
18385	};
18386	
18387	_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
18388		_Api.register( pluralName, val );
18389	
18390		_Api.register( singularName, function () {
18391			var ret = val.apply( this, arguments );
18392	
18393			if ( ret === this ) {
18394				// Returned item is the API instance that was passed in, return it
18395				return this;
18396			}
18397			else if ( ret instanceof _Api ) {
18398				// New API instance returned, want the value from the first item
18399				// in the returned array for the singular result.
18400				return ret.length ?
18401					Array.isArray( ret[0] ) ?
18402						new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
18403						ret[0] :
18404					undefined;
18405			}
18406	
18407			// Non-API return - just fire it back
18408			return ret;
18409		} );
18410	};
18411	
18412	
18413	/**
18414	 * Selector for HTML tables. Apply the given selector to the give array of
18415	 * DataTables settings objects.
18416	 *
18417	 * @param {string|integer} [selector] jQuery selector string or integer
18418	 * @param  {array} Array of DataTables settings objects to be filtered
18419	 * @return {array}
18420	 * @ignore
18421	 */
18422	var __table_selector = function ( selector, a )
18423	{
18424		if ( Array.isArray(selector) ) {
18425			return $.map( selector, function (item) {
18426				return __table_selector(item, a);
18427			} );
18428		}
18429	
18430		// Integer is used to pick out a table by index
18431		if ( typeof selector === 'number' ) {
18432			return [ a[ selector ] ];
18433		}
18434	
18435		// Perform a jQuery selector on the table nodes
18436		var nodes = $.map( a, function (el, i) {
18437			return el.nTable;
18438		} );
18439	
18440		return $(nodes)
18441			.filter( selector )
18442			.map( function (i) {
18443				// Need to translate back from the table node to the settings
18444				var idx = $.inArray( this, nodes );
18445				return a[ idx ];
18446			} )
18447			.toArray();
18448	};
18449	
18450	
18451	
18452	/**
18453	 * Context selector for the API's context (i.e. the tables the API instance
18454	 * refers to.
18455	 *
18456	 * @name    DataTable.Api#tables
18457	 * @param {string|integer} [selector] Selector to pick which tables the iterator
18458	 *   should operate on. If not given, all tables in the current context are
18459	 *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to
18460	 *   select multiple tables or as an integer to select a single table.
18461	 * @returns {DataTable.Api} Returns a new API instance if a selector is given.
18462	 */
18463	_api_register( 'tables()', function ( selector ) {
18464		// A new instance is created if there was a selector specified
18465		return selector !== undefined && selector !== null ?
18466			new _Api( __table_selector( selector, this.context ) ) :
18467			this;
18468	} );
18469	
18470	
18471	_api_register( 'table()', function ( selector ) {
18472		var tables = this.tables( selector );
18473		var ctx = tables.context;
18474	
18475		// Truncate to the first matched table
18476		return ctx.length ?
18477			new _Api( ctx[0] ) :
18478			tables;
18479	} );
18480	
18481	
18482	_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
18483		return this.iterator( 'table', function ( ctx ) {
18484			return ctx.nTable;
18485		}, 1 );
18486	} );
18487	
18488	
18489	_api_registerPlural( 'tables().body()', 'table().body()' , function () {
18490		return this.iterator( 'table', function ( ctx ) {
18491			return ctx.nTBody;
18492		}, 1 );
18493	} );
18494	
18495	
18496	_api_registerPlural( 'tables().header()', 'table().header()' , function () {
18497		return this.iterator( 'table', function ( ctx ) {
18498			return ctx.nTHead;
18499		}, 1 );
18500	} );
18501	
18502	
18503	_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
18504		return this.iterator( 'table', function ( ctx ) {
18505			return ctx.nTFoot;
18506		}, 1 );
18507	} );
18508	
18509	
18510	_api_registerPlural( 'tables().containers()', 'table().container()' , function () {
18511		return this.iterator( 'table', function ( ctx ) {
18512			return ctx.nTableWrapper;
18513		}, 1 );
18514	} );
18515	
18516	
18517	
18518	/**
18519	 * Redraw the tables in the current context.
18520	 */
18521	_api_register( 'draw()', function ( paging ) {
18522		return this.iterator( 'table', function ( settings ) {
18523			if ( paging === 'page' ) {
18524				_fnDraw( settings );
18525			}
18526			else {
18527				if ( typeof paging === 'string' ) {
18528					paging = paging === 'full-hold' ?
18529						false :
18530						true;
18531				}
18532	
18533				_fnReDraw( settings, paging===false );
18534			}
18535		} );
18536	} );
18537	
18538	
18539	
18540	/**
18541	 * Get the current page index.
18542	 *
18543	 * @return {integer} Current page index (zero based)
18544	 *//**
18545	 * Set the current page.
18546	 *
18547	 * Note that if you attempt to show a page which does not exist, DataTables will
18548	 * not throw an error, but rather reset the paging.
18549	 *
18550	 * @param {integer|string} action The paging action to take. This can be one of:
18551	 *  * `integer` - The page index to jump to
18552	 *  * `string` - An action to take:
18553	 *    * `first` - Jump to first page.
18554	 *    * `next` - Jump to the next page
18555	 *    * `previous` - Jump to previous page
18556	 *    * `last` - Jump to the last page.
18557	 * @returns {DataTables.Api} this
18558	 */
18559	_api_register( 'page()', function ( action ) {
18560		if ( action === undefined ) {
18561			return this.page.info().page; // not an expensive call
18562		}
18563	
18564		// else, have an action to take on all tables
18565		return this.iterator( 'table', function ( settings ) {
18566			_fnPageChange( settings, action );
18567		} );
18568	} );
18569	
18570	
18571	/**
18572	 * Paging information for the first table in the current context.
18573	 *
18574	 * If you require paging information for another table, use the `table()` method
18575	 * with a suitable selector.
18576	 *
18577	 * @return {object} Object with the following properties set:
18578	 *  * `page` - Current page index (zero based - i.e. the first page is `0`)
18579	 *  * `pages` - Total number of pages
18580	 *  * `start` - Display index for the first record shown on the current page
18581	 *  * `end` - Display index for the last record shown on the current page
18582	 *  * `length` - Display length (number of records). Note that generally `start
18583	 *    + length = end`, but this is not always true, for example if there are
18584	 *    only 2 records to show on the final page, with a length of 10.
18585	 *  * `recordsTotal` - Full data set length
18586	 *  * `recordsDisplay` - Data set length once the current filtering criterion
18587	 *    are applied.
18588	 */
18589	_api_register( 'page.info()', function ( action ) {
18590		if ( this.context.length === 0 ) {
18591			return undefined;
18592		}
18593	
18594		var
18595			settings   = this.context[0],
18596			start      = settings._iDisplayStart,
18597			len        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
18598			visRecords = settings.fnRecordsDisplay(),
18599			all        = len === -1;
18600	
18601		return {
18602			"page":           all ? 0 : Math.floor( start / len ),
18603			"pages":          all ? 1 : Math.ceil( visRecords / len ),
18604			"start":          start,
18605			"end":            settings.fnDisplayEnd(),
18606			"length":         len,
18607			"recordsTotal":   settings.fnRecordsTotal(),
18608			"recordsDisplay": visRecords,
18609			"serverSide":     _fnDataSource( settings ) === 'ssp'
18610		};
18611	} );
18612	
18613	
18614	/**
18615	 * Get the current page length.
18616	 *
18617	 * @return {integer} Current page length. Note `-1` indicates that all records
18618	 *   are to be shown.
18619	 *//**
18620	 * Set the current page length.
18621	 *
18622	 * @param {integer} Page length to set. Use `-1` to show all records.
18623	 * @returns {DataTables.Api} this
18624	 */
18625	_api_register( 'page.len()', function ( len ) {
18626		// Note that we can't call this function 'length()' because `length`
18627		// is a Javascript property of functions which defines how many arguments
18628		// the function expects.
18629		if ( len === undefined ) {
18630			return this.context.length !== 0 ?
18631				this.context[0]._iDisplayLength :
18632				undefined;
18633		}
18634	
18635		// else, set the page length
18636		return this.iterator( 'table', function ( settings ) {
18637			_fnLengthChange( settings, len );
18638		} );
18639	} );
18640	
18641	
18642	
18643	var __reload = function ( settings, holdPosition, callback ) {
18644		// Use the draw event to trigger a callback
18645		if ( callback ) {
18646			var api = new _Api( settings );
18647	
18648			api.one( 'draw', function () {
18649				callback( api.ajax.json() );
18650			} );
18651		}
18652	
18653		if ( _fnDataSource( settings ) == 'ssp' ) {
18654			_fnReDraw( settings, holdPosition );
18655		}
18656		else {
18657			_fnProcessingDisplay( settings, true );
18658	
18659			// Cancel an existing request
18660			var xhr = settings.jqXHR;
18661			if ( xhr && xhr.readyState !== 4 ) {
18662				xhr.abort();
18663			}
18664	
18665			// Trigger xhr
18666			_fnBuildAjax( settings, [], function( json ) {
18667				_fnClearTable( settings );
18668	
18669				var data = _fnAjaxDataSrc( settings, json );
18670				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
18671					_fnAddData( settings, data[i] );
18672				}
18673	
18674				_fnReDraw( settings, holdPosition );
18675				_fnProcessingDisplay( settings, false );
18676			} );
18677		}
18678	};
18679	
18680	
18681	/**
18682	 * Get the JSON response from the last Ajax request that DataTables made to the
18683	 * server. Note that this returns the JSON from the first table in the current
18684	 * context.
18685	 *
18686	 * @return {object} JSON received from the server.
18687	 */
18688	_api_register( 'ajax.json()', function () {
18689		var ctx = this.context;
18690	
18691		if ( ctx.length > 0 ) {
18692			return ctx[0].json;
18693		}
18694	
18695		// else return undefined;
18696	} );
18697	
18698	
18699	/**
18700	 * Get the data submitted in the last Ajax request
18701	 */
18702	_api_register( 'ajax.params()', function () {
18703		var ctx = this.context;
18704	
18705		if ( ctx.length > 0 ) {
18706			return ctx[0].oAjaxData;
18707		}
18708	
18709		// else return undefined;
18710	} );
18711	
18712	
18713	/**
18714	 * Reload tables from the Ajax data source. Note that this function will
18715	 * automatically re-draw the table when the remote data has been loaded.
18716	 *
18717	 * @param {boolean} [reset=true] Reset (default) or hold the current paging
18718	 *   position. A full re-sort and re-filter is performed when this method is
18719	 *   called, which is why the pagination reset is the default action.
18720	 * @returns {DataTables.Api} this
18721	 */
18722	_api_register( 'ajax.reload()', function ( callback, resetPaging ) {
18723		return this.iterator( 'table', function (settings) {
18724			__reload( settings, resetPaging===false, callback );
18725		} );
18726	} );
18727	
18728	
18729	/**
18730	 * Get the current Ajax URL. Note that this returns the URL from the first
18731	 * table in the current context.
18732	 *
18733	 * @return {string} Current Ajax source URL
18734	 *//**
18735	 * Set the Ajax URL. Note that this will set the URL for all tables in the
18736	 * current context.
18737	 *
18738	 * @param {string} url URL to set.
18739	 * @returns {DataTables.Api} this
18740	 */
18741	_api_register( 'ajax.url()', function ( url ) {
18742		var ctx = this.context;
18743	
18744		if ( url === undefined ) {
18745			// get
18746			if ( ctx.length === 0 ) {
18747				return undefined;
18748			}
18749			ctx = ctx[0];
18750	
18751			return ctx.ajax ?
18752				$.isPlainObject( ctx.ajax ) ?
18753					ctx.ajax.url :
18754					ctx.ajax :
18755				ctx.sAjaxSource;
18756		}
18757	
18758		// set
18759		return this.iterator( 'table', function ( settings ) {
18760			if ( $.isPlainObject( settings.ajax ) ) {
18761				settings.ajax.url = url;
18762			}
18763			else {
18764				settings.ajax = url;
18765			}
18766			// No need to consider sAjaxSource here since DataTables gives priority
18767			// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
18768			// value of `sAjaxSource` redundant.
18769		} );
18770	} );
18771	
18772	
18773	/**
18774	 * Load data from the newly set Ajax URL. Note that this method is only
18775	 * available when `ajax.url()` is used to set a URL. Additionally, this method
18776	 * has the same effect as calling `ajax.reload()` but is provided for
18777	 * convenience when setting a new URL. Like `ajax.reload()` it will
18778	 * automatically redraw the table once the remote data has been loaded.
18779	 *
18780	 * @returns {DataTables.Api} this
18781	 */
18782	_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
18783		// Same as a reload, but makes sense to present it for easy access after a
18784		// url change
18785		return this.iterator( 'table', function ( ctx ) {
18786			__reload( ctx, resetPaging===false, callback );
18787		} );
18788	} );
18789	
18790	
18791	
18792	
18793	var _selector_run = function ( type, selector, selectFn, settings, opts )
18794	{
18795		var
18796			out = [], res,
18797			a, i, ien, j, jen,
18798			selectorType = typeof selector;
18799	
18800		// Can't just check for isArray here, as an API or jQuery instance might be
18801		// given with their array like look
18802		if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
18803			selector = [ selector ];
18804		}
18805	
18806		for ( i=0, ien=selector.length ; i<ien ; i++ ) {
18807			// Only split on simple strings - complex expressions will be jQuery selectors
18808			a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
18809				selector[i].split(',') :
18810				[ selector[i] ];
18811	
18812			for ( j=0, jen=a.length ; j<jen ; j++ ) {
18813				res = selectFn( typeof a[j] === 'string' ? (a[j]).trim() : a[j] );
18814	
18815				if ( res && res.length ) {
18816					out = out.concat( res );
18817				}
18818			}
18819		}
18820	
18821		// selector extensions
18822		var ext = _ext.selector[ type ];
18823		if ( ext.length ) {
18824			for ( i=0, ien=ext.length ; i<ien ; i++ ) {
18825				out = ext[i]( settings, opts, out );
18826			}
18827		}
18828	
18829		return _unique( out );
18830	};
18831	
18832	
18833	var _selector_opts = function ( opts )
18834	{
18835		if ( ! opts ) {
18836			opts = {};
18837		}
18838	
18839		// Backwards compatibility for 1.9- which used the terminology filter rather
18840		// than search
18841		if ( opts.filter && opts.search === undefined ) {
18842			opts.search = opts.filter;
18843		}
18844	
18845		return $.extend( {
18846			search: 'none',
18847			order: 'current',
18848			page: 'all'
18849		}, opts );
18850	};
18851	
18852	
18853	var _selector_first = function ( inst )
18854	{
18855		// Reduce the API instance to the first item found
18856		for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
18857			if ( inst[i].length > 0 ) {
18858				// Assign the first element to the first item in the instance
18859				// and truncate the instance and context
18860				inst[0] = inst[i];
18861				inst[0].length = 1;
18862				inst.length = 1;
18863				inst.context = [ inst.context[i] ];
18864	
18865				return inst;
18866			}
18867		}
18868	
18869		// Not found - return an empty instance
18870		inst.length = 0;
18871		return inst;
18872	};
18873	
18874	
18875	var _selector_row_indexes = function ( settings, opts )
18876	{
18877		var
18878			i, ien, tmp, a=[],
18879			displayFiltered = settings.aiDisplay,
18880			displayMaster = settings.aiDisplayMaster;
18881	
18882		var
18883			search = opts.search,  // none, applied, removed
18884			order  = opts.order,   // applied, current, index (original - compatibility with 1.9)
18885			page   = opts.page;    // all, current
18886	
18887		if ( _fnDataSource( settings ) == 'ssp' ) {
18888			// In server-side processing mode, most options are irrelevant since
18889			// rows not shown don't exist and the index order is the applied order
18890			// Removed is a special case - for consistency just return an empty
18891			// array
18892			return search === 'removed' ?
18893				[] :
18894				_range( 0, displayMaster.length );
18895		}
18896		else if ( page == 'current' ) {
18897			// Current page implies that order=current and filter=applied, since it is
18898			// fairly senseless otherwise, regardless of what order and search actually
18899			// are
18900			for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
18901				a.push( displayFiltered[i] );
18902			}
18903		}
18904		else if ( order == 'current' || order == 'applied' ) {
18905			if ( search == 'none') {
18906				a = displayMaster.slice();
18907			}
18908			else if ( search == 'applied' ) {
18909				a = displayFiltered.slice();
18910			}
18911			else if ( search == 'removed' ) {
18912				// O(n+m) solution by creating a hash map
18913				var displayFilteredMap = {};
18914	
18915				for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) {
18916					displayFilteredMap[displayFiltered[i]] = null;
18917				}
18918	
18919				a = $.map( displayMaster, function (el) {
18920					return ! displayFilteredMap.hasOwnProperty(el) ?
18921						el :
18922						null;
18923				} );
18924			}
18925		}
18926		else if ( order == 'index' || order == 'original' ) {
18927			for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
18928				if ( search == 'none' ) {
18929					a.push( i );
18930				}
18931				else { // applied | removed
18932					tmp = $.inArray( i, displayFiltered );
18933	
18934					if ((tmp === -1 && search == 'removed') ||
18935						(tmp >= 0   && search == 'applied') )
18936					{
18937						a.push( i );
18938					}
18939				}
18940			}
18941		}
18942	
18943		return a;
18944	};
18945	
18946	
18947	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
18948	 * Rows
18949	 *
18950	 * {}          - no selector - use all available rows
18951	 * {integer}   - row aoData index
18952	 * {node}      - TR node
18953	 * {string}    - jQuery selector to apply to the TR elements
18954	 * {array}     - jQuery array of nodes, or simply an array of TR nodes
18955	 *
18956	 */
18957	var __row_selector = function ( settings, selector, opts )
18958	{
18959		var rows;
18960		var run = function ( sel ) {
18961			var selInt = _intVal( sel );
18962			var i, ien;
18963			var aoData = settings.aoData;
18964	
18965			// Short cut - selector is a number and no options provided (default is
18966			// all records, so no need to check if the index is in there, since it
18967			// must be - dev error if the index doesn't exist).
18968			if ( selInt !== null && ! opts ) {
18969				return [ selInt ];
18970			}
18971	
18972			if ( ! rows ) {
18973				rows = _selector_row_indexes( settings, opts );
18974			}
18975	
18976			if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
18977				// Selector - integer
18978				return [ selInt ];
18979			}
18980			else if ( sel === null || sel === undefined || sel === '' ) {
18981				// Selector - none
18982				return rows;
18983			}
18984	
18985			// Selector - function
18986			if ( typeof sel === 'function' ) {
18987				return $.map( rows, function (idx) {
18988					var row = aoData[ idx ];
18989					return sel( idx, row._aData, row.nTr ) ? idx : null;
18990				} );
18991			}
18992	
18993			// Selector - node
18994			if ( sel.nodeName ) {
18995				var rowIdx = sel._DT_RowIndex;  // Property added by DT for fast lookup
18996				var cellIdx = sel._DT_CellIndex;
18997	
18998				if ( rowIdx !== undefined ) {
18999					// Make sure that the row is actually still present in the table
19000					return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ?
19001						[ rowIdx ] :
19002						[];
19003				}
19004				else if ( cellIdx ) {
19005					return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ?
19006						[ cellIdx.row ] :
19007						[];
19008				}
19009				else {
19010					var host = $(sel).closest('*[data-dt-row]');
19011					return host.length ?
19012						[ host.data('dt-row') ] :
19013						[];
19014				}
19015			}
19016	
19017			// ID selector. Want to always be able to select rows by id, regardless
19018			// of if the tr element has been created or not, so can't rely upon
19019			// jQuery here - hence a custom implementation. This does not match
19020			// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
19021			// but to select it using a CSS selector engine (like Sizzle or
19022			// querySelect) it would need to need to be escaped for some characters.
19023			// DataTables simplifies this for row selectors since you can select
19024			// only a row. A # indicates an id any anything that follows is the id -
19025			// unescaped.
19026			if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
19027				// get row index from id
19028				var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
19029				if ( rowObj !== undefined ) {
19030					return [ rowObj.idx ];
19031				}
19032	
19033				// need to fall through to jQuery in case there is DOM id that
19034				// matches
19035			}
19036			
19037			// Get nodes in the order from the `rows` array with null values removed
19038			var nodes = _removeEmpty(
19039				_pluck_order( settings.aoData, rows, 'nTr' )
19040			);
19041	
19042			// Selector - jQuery selector string, array of nodes or jQuery object/
19043			// As jQuery's .filter() allows jQuery objects to be passed in filter,
19044			// it also allows arrays, so this will cope with all three options
19045			return $(nodes)
19046				.filter( sel )
19047				.map( function () {
19048					return this._DT_RowIndex;
19049				} )
19050				.toArray();
19051		};
19052	
19053		return _selector_run( 'row', selector, run, settings, opts );
19054	};
19055	
19056	
19057	_api_register( 'rows()', function ( selector, opts ) {
19058		// argument shifting
19059		if ( selector === undefined ) {
19060			selector = '';
19061		}
19062		else if ( $.isPlainObject( selector ) ) {
19063			opts = selector;
19064			selector = '';
19065		}
19066	
19067		opts = _selector_opts( opts );
19068	
19069		var inst = this.iterator( 'table', function ( settings ) {
19070			return __row_selector( settings, selector, opts );
19071		}, 1 );
19072	
19073		// Want argument shifting here and in __row_selector?
19074		inst.selector.rows = selector;
19075		inst.selector.opts = opts;
19076	
19077		return inst;
19078	} );
19079	
19080	_api_register( 'rows().nodes()', function () {
19081		return this.iterator( 'row', function ( settings, row ) {
19082			return settings.aoData[ row ].nTr || undefined;
19083		}, 1 );
19084	} );
19085	
19086	_api_register( 'rows().data()', function () {
19087		return this.iterator( true, 'rows', function ( settings, rows ) {
19088			return _pluck_order( settings.aoData, rows, '_aData' );
19089		}, 1 );
19090	} );
19091	
19092	_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
19093		return this.iterator( 'row', function ( settings, row ) {
19094			var r = settings.aoData[ row ];
19095			return type === 'search' ? r._aFilterData : r._aSortData;
19096		}, 1 );
19097	} );
19098	
19099	_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
19100		return this.iterator( 'row', function ( settings, row ) {
19101			_fnInvalidate( settings, row, src );
19102		} );
19103	} );
19104	
19105	_api_registerPlural( 'rows().indexes()', 'row().index()', function () {
19106		return this.iterator( 'row', function ( settings, row ) {
19107			return row;
19108		}, 1 );
19109	} );
19110	
19111	_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
19112		var a = [];
19113		var context = this.context;
19114	
19115		// `iterator` will drop undefined values, but in this case we want them
19116		for ( var i=0, ien=context.length ; i<ien ; i++ ) {
19117			for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
19118				var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
19119				a.push( (hash === true ? '#' : '' )+ id );
19120			}
19121		}
19122	
19123		return new _Api( context, a );
19124	} );
19125	
19126	_api_registerPlural( 'rows().remove()', 'row().remove()', function () {
19127		var that = this;
19128	
19129		this.iterator( 'row', function ( settings, row, thatIdx ) {
19130			var data = settings.aoData;
19131			var rowData = data[ row ];
19132			var i, ien, j, jen;
19133			var loopRow, loopCells;
19134	
19135			data.splice( row, 1 );
19136	
19137			// Update the cached indexes
19138			for ( i=0, ien=data.length ; i<ien ; i++ ) {
19139				loopRow = data[i];
19140				loopCells = loopRow.anCells;
19141	
19142				// Rows
19143				if ( loopRow.nTr !== null ) {
19144					loopRow.nTr._DT_RowIndex = i;
19145				}
19146	
19147				// Cells
19148				if ( loopCells !== null ) {
19149					for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
19150						loopCells[j]._DT_CellIndex.row = i;
19151					}
19152				}
19153			}
19154	
19155			// Delete from the display arrays
19156			_fnDeleteIndex( settings.aiDisplayMaster, row );
19157			_fnDeleteIndex( settings.aiDisplay, row );
19158			_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
19159	
19160			// For server-side processing tables - subtract the deleted row from the count
19161			if ( settings._iRecordsDisplay > 0 ) {
19162				settings._iRecordsDisplay--;
19163			}
19164	
19165			// Check for an 'overflow' they case for displaying the table
19166			_fnLengthOverflow( settings );
19167	
19168			// Remove the row's ID reference if there is one
19169			var id = settings.rowIdFn( rowData._aData );
19170			if ( id !== undefined ) {
19171				delete settings.aIds[ id ];
19172			}
19173		} );
19174	
19175		this.iterator( 'table', function ( settings ) {
19176			for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
19177				settings.aoData[i].idx = i;
19178			}
19179		} );
19180	
19181		return this;
19182	} );
19183	
19184	
19185	_api_register( 'rows.add()', function ( rows ) {
19186		var newRows = this.iterator( 'table', function ( settings ) {
19187				var row, i, ien;
19188				var out = [];
19189	
19190				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
19191					row = rows[i];
19192	
19193					if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
19194						out.push( _fnAddTr( settings, row )[0] );
19195					}
19196					else {
19197						out.push( _fnAddData( settings, row ) );
19198					}
19199				}
19200	
19201				return out;
19202			}, 1 );
19203	
19204		// Return an Api.rows() extended instance, so rows().nodes() etc can be used
19205		var modRows = this.rows( -1 );
19206		modRows.pop();
19207		$.merge( modRows, newRows );
19208	
19209		return modRows;
19210	} );
19211	
19212	
19213	
19214	
19215	
19216	/**
19217	 *
19218	 */
19219	_api_register( 'row()', function ( selector, opts ) {
19220		return _selector_first( this.rows( selector, opts ) );
19221	} );
19222	
19223	
19224	_api_register( 'row().data()', function ( data ) {
19225		var ctx = this.context;
19226	
19227		if ( data === undefined ) {
19228			// Get
19229			return ctx.length && this.length ?
19230				ctx[0].aoData[ this[0] ]._aData :
19231				undefined;
19232		}
19233	
19234		// Set
19235		var row = ctx[0].aoData[ this[0] ];
19236		row._aData = data;
19237	
19238		// If the DOM has an id, and the data source is an array
19239		if ( Array.isArray( data ) && row.nTr && row.nTr.id ) {
19240			_fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id );
19241		}
19242	
19243		// Automatically invalidate
19244		_fnInvalidate( ctx[0], this[0], 'data' );
19245	
19246		return this;
19247	} );
19248	
19249	
19250	_api_register( 'row().node()', function () {
19251		var ctx = this.context;
19252	
19253		return ctx.length && this.length ?
19254			ctx[0].aoData[ this[0] ].nTr || null :
19255			null;
19256	} );
19257	
19258	
19259	_api_register( 'row.add()', function ( row ) {
19260		// Allow a jQuery object to be passed in - only a single row is added from
19261		// it though - the first element in the set
19262		if ( row instanceof $ && row.length ) {
19263			row = row[0];
19264		}
19265	
19266		var rows = this.iterator( 'table', function ( settings ) {
19267			if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
19268				return _fnAddTr( settings, row )[0];
19269			}
19270			return _fnAddData( settings, row );
19271		} );
19272	
19273		// Return an Api.rows() extended instance, with the newly added row selected
19274		return this.row( rows[0] );
19275	} );
19276	
19277	
19278	$(document).on('plugin-init.dt', function (e, context) {
19279		var api = new _Api( context );
19280		
19280api.on( 'stateSaveParams', function ( e, settings, data ) {
19281			var indexes = api.rows().iterator( 'row', function ( settings, idx ) {
19282				return settings.aoData[idx]._detailsShow ? idx : undefined;
19283			});
19284	
19285			data.childRows = api.rows( indexes ).ids( true ).toArray();
19286		})
19287	
19288		var loaded = api.state.loaded();
19289	
19290		if ( loaded && loaded.childRows ) {
19291			api.rows( loaded.childRows ).every( function () {
19292				_fnCallbackFire( context, null, 'requestChild', [ this ] )
19293			})
19294		}
19295	})
19296	
19297	var __details_add = function ( ctx, row, data, klass )
19298	{
19299		// Convert to array of TR elements
19300		var rows = [];
19301		var addRow = function ( r, k ) {
19302			// Recursion to allow for arrays of jQuery objects
19303			if ( Array.isArray( r ) || r instanceof $ ) {
19304				for ( var i=0, ien=r.length ; i<ien ; i++ ) {
19305					addRow( r[i], k );
19306				}
19307				return;
19308			}
19309	
19310			// If we get a TR element, then just add it directly - up to the dev
19311			// to add the correct number of columns etc
19312			if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
19313				rows.push( r );
19314			}
19315			else {
19316				// Otherwise create a row with a wrapper
19317				var created = $('<tr><td></td></tr>').addClass( k );
19318				$('td', created)
19319					.addClass( k )
19320					.html( r )
19321					[0].colSpan = _fnVisbleColumns( ctx );
19322	
19323				rows.push( created[0] );
19324			}
19325		};
19326	
19327		addRow( data, klass );
19328	
19329		if ( row._details ) {
19330			row._details.detach();
19331		}
19332	
19333		row._details = $(rows);
19334	
19335		// If the children were already shown, that state should be retained
19336		if ( row._detailsShow ) {
19337			row._details.insertAfter( row.nTr );
19338		}
19339	};
19340	
19341	
19342	var __details_remove = function ( api, idx )
19343	{
19344		var ctx = api.context;
19345	
19346		if ( ctx.length ) {
19347			var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
19348	
19349			if ( row && row._details ) {
19350				row._details.remove();
19351	
19352				row._detailsShow = undefined;
19353				row._details = undefined;
19354				$( row.nTr ).removeClass( 'dt-hasChild' );
19355				_fnSaveState( ctx[0] );
19356			}
19357		}
19358	};
19359	
19360	
19361	var __details_display = function ( api, show ) {
19362		var ctx = api.context;
19363	
19364		if ( ctx.length && api.length ) {
19365			var row = ctx[0].aoData[ api[0] ];
19366	
19367			if ( row._details ) {
19368				row._detailsShow = show;
19369	
19370				if ( show ) {
19371					row._details.insertAfter( row.nTr );
19372					$( row.nTr ).addClass( 'dt-hasChild' );
19373				}
19374				else {
19375					row._details.detach();
19376					$( row.nTr ).removeClass( 'dt-hasChild' );
19377				}
19378	
19379				_fnCallbackFire( ctx[0], null, 'childRow', [ show, api.row( api[0] ) ] )
19380	
19381				__details_events( ctx[0] );
19382				_fnSaveState( ctx[0] );
19383			}
19384		}
19385	};
19386	
19387	
19388	var __details_events = function ( settings )
19389	{
19390		var api = new _Api( settings );
19391		var namespace = '.dt.DT_details';
19392		var drawEvent = 'draw'+namespace;
19393		var colvisEvent = 'column-visibility
vendor: 22,869 bytes, lines 19393-20254
19393'+namespace;
19394		var destroyEvent = 'destroy'+namespace;
19395		var data = settings.aoData;
19396	
19397		api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
19398	
19399		if ( _pluck( data, '_details' ).length > 0 ) {
19400			// On each draw, insert the required elements into the document
19401			api.on( drawEvent, function ( e, ctx ) {
19402				if ( settings !== ctx ) {
19403					return;
19404				}
19405	
19406				api.rows( {page:'current'} ).eq(0).each( function (idx) {
19407					// Internal data grab
19408					var row = data[ idx ];
19409	
19410					if ( row._detailsShow ) {
19411						row._details.insertAfter( row.nTr );
19412					}
19413				} );
19414			} );
19415	
19416			// Column visibility change - update the colspan
19417			api.on( colvisEvent, function ( e, ctx, idx, vis ) {
19418				if ( settings !== ctx ) {
19419					return;
19420				}
19421	
19422				// Update the colspan for the details rows (note, only if it already has
19423				// a colspan)
19424				var row, visible = _fnVisbleColumns( ctx );
19425	
19426				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
19427					row = data[i];
19428	
19429					if ( row._details ) {
19430						row._details.children('td[colspan]').attr('colspan', visible );
19431					}
19432				}
19433			} );
19434	
19435			// Table destroyed - nuke any child rows
19436			api.on( destroyEvent, function ( e, ctx ) {
19437				if ( settings !== ctx ) {
19438					return;
19439				}
19440	
19441				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
19442					if ( data[i]._details ) {
19443						__details_remove( api, i );
19444					}
19445				}
19446			} );
19447		}
19448	};
19449	
19450	// Strings for the method names to help minification
19451	var _emp = '';
19452	var _child_obj = _emp+'row().child';
19453	var _child_mth = _child_obj+'()';
19454	
19455	// data can be:
19456	//  tr
19457	//  string
19458	//  jQuery or array of any of the above
19459	_api_register( _child_mth, function ( data, klass ) {
19460		var ctx = this.context;
19461	
19462		if ( data === undefined ) {
19463			// get
19464			return ctx.length && this.length ?
19465				ctx[0].aoData[ this[0] ]._details :
19466				undefined;
19467		}
19468		else if ( data === true ) {
19469			// show
19470			this.child.show();
19471		}
19472		else if ( data === false ) {
19473			// remove
19474			__details_remove( this );
19475		}
19476		else if ( ctx.length && this.length ) {
19477			// set
19478			__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
19479		}
19480	
19481		return this;
19482	} );
19483	
19484	
19485	_api_register( [
19486		_child_obj+'.show()',
19487		_child_mth+'.show()' // only when `child()` was called with parameters (without
19488	], function ( show ) {   // it returns an object and this method is not executed)
19489		__details_display( this, true );
19490		return this;
19491	} );
19492	
19493	
19494	_api_register( [
19495		_child_obj+'.hide()',
19496		_child_mth+'.hide()' // only when `child()` was called with parameters (without
19497	], function () {         // it returns an object and this method is not executed)
19498		__details_display( this, false );
19499		return this;
19500	} );
19501	
19502	
19503	_api_register( [
19504		_child_obj+'.remove()',
19505		_child_mth+'.remove()' // only when `child()` was called with parameters (without
19506	], function () {           // it returns an object and this method is not executed)
19507		__details_remove( this );
19508		return this;
19509	} );
19510	
19511	
19512	_api_register( _child_obj+'.isShown()', function () {
19513		var ctx = this.context;
19514	
19515		if ( ctx.length && this.length ) {
19516			// _detailsShown as false or undefined will fall through to return false
19517			return ctx[0].aoData[ this[0] ]._detailsShow || false;
19518		}
19519		return false;
19520	} );
19521	
19522	
19523	
19524	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
19525	 * Columns
19526	 *
19527	 * {integer}           - column index (>=0 count from left, <0 count from right)
19528	 * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
19529	 * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
19530	 * "{string}:name"     - column name
19531	 * "{string}"          - jQuery selector on column header nodes
19532	 *
19533	 */
19534	
19535	// can be an array of these items, comma separated list, or an array of comma
19536	// separated lists
19537	
19538	var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
19539	
19540	
19541	// r1 and r2 are redundant - but it means that the parameters match for the
19542	// iterator callback in columns().data()
19543	var __columnData = function ( settings, column, r1, r2, rows ) {
19544		var a = [];
19545		for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
19546			a.push( _fnGetCellData( settings, rows[row], column ) );
19547		}
19548		return a;
19549	};
19550	
19551	
19552	var __column_selector = function ( settings, selector, opts )
19553	{
19554		var
19555			columns = settings.aoColumns,
19556			names = _pluck( columns, 'sName' ),
19557			nodes = _pluck( columns, 'nTh' );
19558	
19559		var run = function ( s ) {
19560			var selInt = _intVal( s );
19561	
19562			// Selector - all
19563			if ( s === '' ) {
19564				return _range( columns.length );
19565			}
19566	
19567			// Selector - index
19568			if ( selInt !== null ) {
19569				return [ selInt >= 0 ?
19570					selInt : // Count from left
19571					columns.length + selInt // Count from right (+ because its a negative value)
19572				];
19573			}
19574	
19575			// Selector = function
19576			if ( typeof s === 'function' ) {
19577				var rows = _selector_row_indexes( settings, opts );
19578	
19579				return $.map( columns, function (col, idx) {
19580					return s(
19581							idx,
19582							__columnData( settings, idx, 0, 0, rows ),
19583							nodes[ idx ]
19584						) ? idx : null;
19585				} );
19586			}
19587	
19588			// jQuery or string selector
19589			var match = typeof s === 'string' ?
19590				s.match( __re_column_selector ) :
19591				'';
19592	
19593			if ( match ) {
19594				switch( match[2] ) {
19595					case 'visIdx':
19596					case 'visible':
19597						var idx = parseInt( match[1], 10 );
19598						// Visible index given, convert to column index
19599						if ( idx < 0 ) {
19600							// Counting from the right
19601							var visColumns = $.map( columns, function (col,i) {
19602								return col.bVisible ? i : null;
19603							} );
19604							return [ visColumns[ visColumns.length + idx ] ];
19605						}
19606						// Counting from the left
19607						return [ _fnVisibleToColumnIndex( settings, idx ) ];
19608	
19609					case 'name':
19610						// match by name. `names` is column index complete and in order
19611						return $.map( names, function (name, i) {
19612							return name === match[1] ? i : null;
19613						} );
19614	
19615					default:
19616						return [];
19617				}
19618			}
19619	
19620			// Cell in the table body
19621			if ( s.nodeName && s._DT_CellIndex ) {
19622				return [ s._DT_CellIndex.column ];
19623			}
19624	
19625			// jQuery selector on the TH elements for the columns
19626			var jqResult = $( nodes )
19627				.filter( s )
19628				.map( function () {
19629					return $.inArray( this, nodes ); // `nodes` is column index complete and in order
19630				} )
19631				.toArray();
19632	
19633			if ( jqResult.length || ! s.nodeName ) {
19634				return jqResult;
19635			}
19636	
19637			// Otherwise a node which might have a `dt-column` data attribute, or be
19638			// a child or such an element
19639			var host = $(s).closest('*[data-dt-column]');
19640			return host.length ?
19641				[ host.data('dt-column') ] :
19642				[];
19643		};
19644	
19645		return _selector_run( 'column', selector, run, settings, opts );
19646	};
19647	
19648	
19649	var __setColumnVis = function ( settings, column, vis ) {
19650		var
19651			cols = settings.aoColumns,
19652			col  = cols[ column ],
19653			data = settings.aoData,
19654			row, cells, i, ien, tr;
19655	
19656		// Get
19657		if ( vis === undefined ) {
19658			return col.bVisible;
19659		}
19660	
19661		// Set
19662		// No change
19663		if ( col.bVisible === vis ) {
19664			return;
19665		}
19666	
19667		if ( vis ) {
19668			// Insert column
19669			// Need to decide if we should use appendChild or insertBefore
19670			var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
19671	
19672			for ( i=0, ien=data.length ; i<ien ; i++ ) {
19673				tr = data[i].nTr;
19674				cells = data[i].anCells;
19675	
19676				if ( tr ) {
19677					// insertBefore can act like appendChild if 2nd arg is null
19678					tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
19679				}
19680			}
19681		}
19682		else {
19683			// Remove column
19684			$( _pluck( settings.aoData, 'anCells', column ) ).detach();
19685		}
19686	
19687		// Common actions
19688		col.bVisible = vis;
19689	};
19690	
19691	
19692	_api_register( 'columns()', function ( selector, opts ) {
19693		// argument shifting
19694		if ( selector === undefined ) {
19695			selector = '';
19696		}
19697		else if ( $.isPlainObject( selector ) ) {
19698			opts = selector;
19699			selector = '';
19700		}
19701	
19702		opts = _selector_opts( opts );
19703	
19704		var inst = this.iterator( 'table', function ( settings ) {
19705			return __column_selector( settings, selector, opts );
19706		}, 1 );
19707	
19708		// Want argument shifting here and in _row_selector?
19709		inst.selector.cols = selector;
19710		inst.selector.opts = opts;
19711	
19712		return inst;
19713	} );
19714	
19715	_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
19716		return this.iterator( 'column', function ( settings, column ) {
19717			return settings.aoColumns[column].nTh;
19718		}, 1 );
19719	} );
19720	
19721	_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
19722		return this.iterator( 'column', function ( settings, column ) {
19723			return settings.aoColumns[column].nTf;
19724		}, 1 );
19725	} );
19726	
19727	_api_registerPlural( 'columns().data()', 'column().data()', function () {
19728		return this.iterator( 'column-rows', __columnData, 1 );
19729	} );
19730	
19731	_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
19732		return this.iterator( 'column', function ( settings, column ) {
19733			return settings.aoColumns[column].mData;
19734		}, 1 );
19735	} );
19736	
19737	_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
19738		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
19739			return _pluck_order( settings.aoData, rows,
19740				type === 'search' ? '_aFilterData' : '_aSortData', column
19741			);
19742		}, 1 );
19743	} );
19744	
19745	_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
19746		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
19747			return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
19748		}, 1 );
19749	} );
19750	
19751	_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
19752		var that = this;
19753		var ret = this.iterator( 'column', function ( settings, column ) {
19754			if ( vis === undefined ) {
19755				return settings.aoColumns[ column ].bVisible;
19756			} // else
19757			__setColumnVis( settings, column, vis );
19758		} );
19759	
19760		// Group the column visibility changes
19761		if ( vis !== undefined ) {
19762			this.iterator( 'table', function ( settings ) {
19763				// Redraw the header after changes
19764				_fnDrawHead( settings, settings.aoHeader );
19765				_fnDrawHead( settings, settings.aoFooter );
19766		
19767				// Update colspan for no records display. Child rows and extensions will use their own
19768				// listeners to do this - only need to update the empty table item here
19769				if ( ! settings.aiDisplay.length ) {
19770					$(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings));
19771				}
19772		
19773				_fnSaveState( settings );
19774	
19775				// Second loop once the first is done for events
19776				that.iterator( 'column', function ( settings, column ) {
19777					_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
19778				} );
19779	
19780				if ( calc === undefined || calc ) {
19781					that.columns.adjust();
19782				}
19783			});
19784		}
19785	
19786		return ret;
19787	} );
19788	
19789	_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
19790		return this.iterator( 'column', function ( settings, column ) {
19791			return type === 'visible' ?
19792				_fnColumnIndexToVisible( settings, column ) :
19793				column;
19794		}, 1 );
19795	} );
19796	
19797	_api_register( 'columns.adjust()', function () {
19798		return this.iterator( 'table', function ( settings ) {
19799			_fnAdjustColumnSizing( settings );
19800		}, 1 );
19801	} );
19802	
19803	_api_register( 'column.index()', function ( type, idx ) {
19804		if ( this.context.length !== 0 ) {
19805			var ctx = this.context[0];
19806	
19807			if ( type === 'fromVisible' || type === 'toData' ) {
19808				return _fnVisibleToColumnIndex( ctx, idx );
19809			}
19810			else if ( type === 'fromData' || type === 'toVisible' ) {
19811				return _fnColumnIndexToVisible( ctx, idx );
19812			}
19813		}
19814	} );
19815	
19816	_api_register( 'column()', function ( selector, opts ) {
19817		return _selector_first( this.columns( selector, opts ) );
19818	} );
19819	
19820	var __cell_selector = function ( settings, selector, opts )
19821	{
19822		var data = settings.aoData;
19823		var rows = _selector_row_indexes( settings, opts );
19824		var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
19825		var allCells = $(_flatten( [], cells ));
19826		var row;
19827		var columns = settings.aoColumns.length;
19828		var a, i, ien, j, o, host;
19829	
19830		var run = function ( s ) {
19831			var fnSelector = typeof s === 'function';
19832	
19833			if ( s === null || s === undefined || fnSelector ) {
19834				// All cells and function selectors
19835				a = [];
19836	
19837				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
19838					row = rows[i];
19839	
19840					for ( j=0 ; j<columns ; j++ ) {
19841						o = {
19842							row: row,
19843							column: j
19844						};
19845	
19846						if ( fnSelector ) {
19847							// Selector - function
19848							host = data[ row ];
19849	
19850							if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
19851								a.push( o );
19852							}
19853						}
19854						else {
19855							// Selector - all
19856							a.push( o );
19857						}
19858					}
19859				}
19860	
19861				return a;
19862			}
19863			
19864			// Selector - index
19865			if ( $.isPlainObject( s ) ) {
19866				// Valid cell index and its in the array of selectable rows
19867				return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ?
19868					[s] :
19869					[];
19870			}
19871	
19872			// Selector - jQuery filtered cells
19873			var jqResult = allCells
19874				.filter( s )
19875				.map( function (i, el) {
19876					return { // use a new object, in case someone changes the values
19877						row:    el._DT_CellIndex.row,
19878						column: el._DT_CellIndex.column
19879	 				};
19880				} )
19881				.toArray();
19882	
19883			if ( jqResult.length || ! s.nodeName ) {
19884				return jqResult;
19885			}
19886	
19887			// Otherwise the selector is a node, and there is one last option - the
19888			// element might be a child of an element which has dt-row and dt-column
19889			// data attributes
19890			host = $(s).closest('*[data-dt-row]');
19891			return host.length ?
19892				[ {
19893					row: host.data('dt-row'),
19894					column: host.data('dt-column')
19895				} ] :
19896				[];
19897		};
19898	
19899		return _selector_run( 'cell', selector, run, settings, opts );
19900	};
19901	
19902	
19903	
19904	
19905	_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
19906		// Argument shifting
19907		if ( $.isPlainObject( rowSelector ) ) {
19908			// Indexes
19909			if ( rowSelector.row === undefined ) {
19910				// Selector options in first parameter
19911				opts = rowSelector;
19912				rowSelector = null;
19913			}
19914			else {
19915				// Cell index objects in first parameter
19916				opts = columnSelector;
19917				columnSelector = null;
19918			}
19919		}
19920		if ( $.isPlainObject( columnSelector ) ) {
19921			opts = columnSelector;
19922			columnSelector = null;
19923		}
19924	
19925		// Cell selector
19926		if ( columnSelector === null || columnSelector === undefined ) {
19927			return this.iterator( 'table', function ( settings ) {
19928				return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
19929			} );
19930		}
19931	
19932		// The default built in options need to apply to row and columns
19933		var internalOpts = opts ? {
19934			page: opts.page,
19935			order: opts.order,
19936			search: opts.search
19937		} : {};
19938	
19939		// Row + column selector
19940		var columns = this.columns( columnSelector, internalOpts );
19941		var rows = this.rows( rowSelector, internalOpts );
19942		var i, ien, j, jen;
19943	
19944		var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) {
19945			var a = [];
19946	
19947			for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
19948				for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
19949					a.push( {
19950						row:    rows[idx][i],
19951						column: columns[idx][j]
19952					} );
19953				}
19954			}
19955	
19956			return a;
19957		}, 1 );
19958	
19959		// There is currently only one extension which uses a cell selector extension
19960		// It is a _major_ performance drag to run this if it isn't needed, so this is
19961		// an extension specific check at the moment
19962		var cells = opts && opts.selected ?
19963			this.cells( cellsNoOpts, opts ) :
19964			cellsNoOpts;
19965	
19966		$.extend( cells.selector, {
19967			cols: columnSelector,
19968			rows: rowSelector,
19969			opts: opts
19970		} );
19971	
19972		return cells;
19973	} );
19974	
19975	
19976	_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
19977		return this.iterator( 'cell', function ( settings, row, column ) {
19978			var data = settings.aoData[ row ];
19979	
19980			return data && data.anCells ?
19981				data.anCells[ column ] :
19982				undefined;
19983		}, 1 );
19984	} );
19985	
19986	
19987	_api_register( 'cells().data()', function () {
19988		return this.iterator( 'cell', function ( settings, row, column ) {
19989			return _fnGetCellData( settings, row, column );
19990		}, 1 );
19991	} );
19992	
19993	
19994	_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
19995		type = type === 'search' ? '_aFilterData' : '_aSortData';
19996	
19997		return this.iterator( 'cell', function ( settings, row, column ) {
19998			return settings.aoData[ row ][ type ][ column ];
19999		}, 1 );
20000	} );
20001	
20002	
20003	_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
20004		return this.iterator( 'cell', function ( settings, row, column ) {
20005			return _fnGetCellData( settings, row, column, type );
20006		}, 1 );
20007	} );
20008	
20009	
20010	_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
20011		return this.iterator( 'cell', function ( settings, row, column ) {
20012			return {
20013				row: row,
20014				column: column,
20015				columnVisible: _fnColumnIndexToVisible( settings, column )
20016			};
20017		}, 1 );
20018	} );
20019	
20020	
20021	_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
20022		return this.iterator( 'cell', function ( settings, row, column ) {
20023			_fnInvalidate( settings, row, src, column );
20024		} );
20025	} );
20026	
20027	
20028	
20029	_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
20030		return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
20031	} );
20032	
20033	
20034	_api_register( 'cell().data()', function ( data ) {
20035		var ctx = this.context;
20036		var cell = this[0];
20037	
20038		if ( data === undefined ) {
20039			// Get
20040			return ctx.length && cell.length ?
20041				_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
20042				undefined;
20043		}
20044	
20045		// Set
20046		_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
20047		_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
20048	
20049		return this;
20050	} );
20051	
20052	
20053	
20054	/**
20055	 * Get current ordering (sorting) that has been applied to the table.
20056	 *
20057	 * @returns {array} 2D array containing the sorting information for the first
20058	 *   table in the current context. Each element in the parent array represents
20059	 *   a column being sorted upon (i.e. multi-sorting with two columns would have
20060	 *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
20061	 *   the column index that the sorting condition applies to, the second is the
20062	 *   direction of the sort (`desc` or `asc`) and, optionally, the third is the
20063	 *   index of the sorting order from the `column.sorting` initialisation array.
20064	 *//**
20065	 * Set the ordering for the table.
20066	 *
20067	 * @param {integer} order Column index to sort upon.
20068	 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
20069	 * @returns {DataTables.Api} this
20070	 *//**
20071	 * Set the ordering for the table.
20072	 *
20073	 * @param {array} order 1D array of sorting information to be applied.
20074	 * @param {array} [...] Optional additional sorting conditions
20075	 * @returns {DataTables.Api} this
20076	 *//**
20077	 * Set the ordering for the table.
20078	 *
20079	 * @param {array} order 2D array of sorting information to be applied.
20080	 * @returns {DataTables.Api} this
20081	 */
20082	_api_register( 'order()', function ( order, dir ) {
20083		var ctx = this.context;
20084	
20085		if ( order === undefined ) {
20086			// get
20087			return ctx.length !== 0 ?
20088				ctx[0].aaSorting :
20089				undefined;
20090		}
20091	
20092		// set
20093		if ( typeof order === 'number' ) {
20094			// Simple column / direction passed in
20095			order = [ [ order, dir ] ];
20096		}
20097		else if ( order.length && ! Array.isArray( order[0] ) ) {
20098			// Arguments passed in (list of 1D arrays)
20099			order = Array.prototype.slice.call( arguments );
20100		}
20101		// otherwise a 2D array was passed in
20102	
20103		return this.iterator( 'table', function ( settings ) {
20104			settings.aaSorting = order.slice();
20105		} );
20106	} );
20107	
20108	
20109	/**
20110	 * Attach a sort listener to an element for a given column
20111	 *
20112	 * @param {node|jQuery|string} node Identifier for the element(s) to attach the
20113	 *   listener to. This can take the form of a single DOM node, a jQuery
20114	 *   collection of nodes or a jQuery selector which will identify the node(s).
20115	 * @param {integer} column the column that a click on this node will sort on
20116	 * @param {function} [callback] callback function when sort is run
20117	 * @returns {DataTables.Api} this
20118	 */
20119	_api_register( 'order.listener()', function ( node, column, callback ) {
20120		return this.iterator( 'table', function ( settings ) {
20121			_fnSortAttachListener( settings, node, column, callback );
20122		} );
20123	} );
20124	
20125	
20126	_api_register( 'order.fixed()', function ( set ) {
20127		if ( ! set ) {
20128			var ctx = this.context;
20129			var fixed = ctx.length ?
20130				ctx[0].aaSortingFixed :
20131				undefined;
20132	
20133			return Array.isArray( fixed ) ?
20134				{ pre: fixed } :
20135				fixed;
20136		}
20137	
20138		return this.iterator( 'table', function ( settings ) {
20139			settings.aaSortingFixed = $.extend( true, {}, set );
20140		} );
20141	} );
20142	
20143	
20144	// Order by the selected column(s)
20145	_api_register( [
20146		'columns().order()',
20147		'column().order()'
20148	], function ( dir ) {
20149		var that = this;
20150	
20151		return this.iterator( 'table', function ( settings, i ) {
20152			var sort = [];
20153	
20154			$.each( that[i], function (j, col) {
20155				sort.push( [ col, dir ] );
20156			} );
20157	
20158			settings.aaSorting = sort;
20159		} );
20160	} );
20161	
20162	
20163	
20164	_api_register( 'search()', function ( input, regex, smart, caseInsen ) {
20165		var ctx = this.context;
20166	
20167		if ( input === undefined ) {
20168			// get
20169			return ctx.length !== 0 ?
20170				ctx[0].oPreviousSearch.sSearch :
20171				undefined;
20172		}
20173	
20174		// set
20175		return this.iterator( 'table', function ( settings ) {
20176			if ( ! settings.oFeatures.bFilter ) {
20177				return;
20178			}
20179	
20180			_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
20181				"sSearch": input+"",
20182				"bRegex":  regex === null ? false : regex,
20183				"bSmart":  smart === null ? true  : smart,
20184				"bCaseInsensitive": caseInsen === null ? true : caseInsen
20185			} ), 1 );
20186		} );
20187	} );
20188	
20189	
20190	_api_registerPlural(
20191		'columns().search()',
20192		'column().search()',
20193		function ( input, regex, smart, caseInsen ) {
20194			return this.iterator( 'column', function ( settings, column ) {
20195				var preSearch = settings.aoPreSearchCols;
20196	
20197				if ( input === undefined ) {
20198					// get
20199					return preSearch[ column ].sSearch;
20200				}
20201	
20202				// set
20203				if ( ! settings.oFeatures.bFilter ) {
20204					return;
20205				}
20206	
20207				$.extend( preSearch[ column ], {
20208					"sSearch": input+"",
20209					"bRegex":  regex === null ? false : regex,
20210					"bSmart":  smart === null ? true  : smart,
20211					"bCaseInsensitive": caseInsen === null ? true : caseInsen
20212				} );
20213	
20214				_fnFilterComplete( settings, settings.oPreviousSearch, 1 );
20215			} );
20216		}
20217	);
20218	
20219	/*
20220	 * State API methods
20221	 */
20222	
20223	_api_register( 'state()', function () {
20224		return this.context.length ?
20225			this.context[0].oSavedState :
20226			null;
20227	} );
20228	
20229	
20230	_api_register( 'state.clear()', function () {
20231		return this.iterator( 'table', function ( settings ) {
20232			// Save an empty object
20233			settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
20234		} );
20235	} );
20236	
20237	
20238	_api_register( 'state.loaded()', function () {
20239		return this.context.length ?
20240			this.context[0].oLoadedState :
20241			null;
20242	} );
20243	
20244	
20245	_api_register( 'state.save()', function () {
20246		return this.iterator( 'table', function ( settings ) {
20247			_fnSaveState( settings );
20248		} );
20249	} );
20250	
20251	
20252	
20253	/**
20254	 * 
20254Provide a common method for plug-ins to check the version of DataTables being
20255	 * used, in order to ensure compatibility.
20256	 *
20257	 *  @param {string} version Version string to check for, in the format "X.Y.Z".
20258	 *    Note that the formats "X" and "X.Y" are also acceptable.
20259	 *  @returns {boolean} true if this version of DataTables is greater or equal to
20260	 *    the required version, or false if this version of DataTales is not
20261	 *    suitable
20262	 *  @static
20263	 *  @dtopt API-Static
20264	 *
20265	 *  @example
20266	 *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
20267	 */
20268	DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
20269	{
20270		var aThis = DataTable.version.split('.');
20271		var aThat = version.split('.');
20272		var iThis, iThat;
20273	
20274		for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
20275			iThis = parseInt( aThis[i], 10 ) || 0;
20276			iThat = parseInt( aThat[i], 10 ) || 0;
20277	
20278			// Parts are the same, keep comparing
20279			if (iThis === iThat) {
20280				continue;
20281			}
20282	
20283			// Parts are different, return immediately
20284			return iThis > iThat;
20285		}
20286	
20287		return true;
20288	};
20289	
20290	
20291	/**
20292	 * Check if a `<table>` node is a DataTable table already or not.
20293	 *
20294	 *  @param {node|jquery|string} table Table node, jQuery object or jQuery
20295	 *      selector for the table to test. Note that if more than more than one
20296	 *      table is passed on, only the first will be checked
20297	 *  @returns {boolean} true the table given is a DataTable, or false otherwise
20298	 *  @static
20299	 *  @dtopt API-Static
20300	 *
20301	 *  @example
20302	 *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
20303	 *      $('#example').dataTable();
20304	 *    }
20305	 */
20306	DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
20307	{
20308		var t = $(table).get(0);
20309		var is = false;
20310	
20311		if ( table instanceof DataTable.Api ) {
20312			return true;
20313		}
20314	
20315		$.each( DataTable.settings, function (i, o) {
20316			var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
20317			var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
20318	
20319			if ( o.nTable === t || head === t || foot === t ) {
20320				is = true;
20321			}
20322		} );
20323	
20324		return is;
20325	};
20326	
20327	
20328	/**
20329	 * Get all DataTable tables that have been initialised - optionally you can
20330	 * select to get only currently visible tables.
20331	 *
20332	 *  @param {boolean} [visible=false] Flag to indicate if you want all (default)
20333	 *    or visible tables only.
20334	 *  @returns {array} Array of `table` nodes (not DataTable instances) which are
20335	 *    DataTables
20336	 *  @static
20337	 *  @dtopt API-Static
20338	 *
20339	 *  @example
20340	 *    $.each( $.fn.dataTable.tables(true), function () {
20341	 *      $(table).DataTable().columns.adjust();
20342	 *    } );
20343	 */
20344	DataTable.tables = DataTable.fnTables = function ( visible )
20345	{
20346		var api = false;
vendor: 7,568 bytes, lines 20347-20607
20347	
20348		if ( $.isPlainObject( visible ) ) {
20349			api = visible.api;
20350			visible = visible.visible;
20351		}
20352	
20353		var a = $.map( DataTable.settings, function (o) {
20354			if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
20355				return o.nTable;
20356			}
20357		} );
20358	
20359		return api ?
20360			new _Api( a ) :
20361			a;
20362	};
20363	
20364	
20365	/**
20366	 * Convert from camel case parameters to Hungarian notation. This is made public
20367	 * for the extensions to provide the same ability as DataTables core to accept
20368	 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
20369	 * parameters.
20370	 *
20371	 *  @param {object} src The model object which holds all parameters that can be
20372	 *    mapped.
20373	 *  @param {object} user The object to convert from camel case to Hungarian.
20374	 *  @param {boolean} force When set to `true`, properties which already have a
20375	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
20376	 *    won't be.
20377	 */
20378	DataTable.camelToHungarian = _fnCamelToHungarian;
20379	
20380	
20381	
20382	/**
20383	 *
20384	 */
20385	_api_register( '$()', function ( selector, opts ) {
20386		var
20387			rows   = this.rows( opts ).nodes(), // Get all rows
20388			jqRows = $(rows);
20389	
20390		return $( [].concat(
20391			jqRows.filter( selector ).toArray(),
20392			jqRows.find( selector ).toArray()
20393		) );
20394	} );
20395	
20396	
20397	// jQuery functions to operate on the tables
20398	$.each( [ 'on', 'one', 'off' ], function (i, key) {
20399		_api_register( key+'()', function ( /* event, handler */ ) {
20400			var args = Array.prototype.slice.call(arguments);
20401	
20402			// Add the `dt` namespace automatically if it isn't already present
20403			args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
20404				return ! e.match(/\.dt\b/) ?
20405					e+'.dt' :
20406					e;
20407				} ).join( ' ' );
20408	
20409			var inst = $( this.tables().nodes() );
20410			inst[key].apply( inst, args );
20411			return this;
20412		} );
20413	} );
20414	
20415	
20416	_api_register( 'clear()', function () {
20417		return this.iterator( 'table', function ( settings ) {
20418			_fnClearTable( settings );
20419		} );
20420	} );
20421	
20422	
20423	_api_register( 'settings()', function () {
20424		return new _Api( this.context, this.context );
20425	} );
20426	
20427	
20428	_api_register( 'init()', function () {
20429		var ctx = this.context;
20430		return ctx.length ? ctx[0].oInit : null;
20431	} );
20432	
20433	
20434	_api_register( 'data()', function () {
20435		return this.iterator( 'table', function ( settings ) {
20436			return _pluck( settings.aoData, '_aData' );
20437		} ).flatten();
20438	} );
20439	
20440	
20441	_api_register( 'destroy()', function ( remove ) {
20442		remove = remove || false;
20443	
20444		return this.iterator( 'table', function ( settings ) {
20445			var orig      = settings.nTableWrapper.parentNode;
20446			var classes   = settings.oClasses;
20447			var table     = settings.nTable;
20448			var tbody     = settings.nTBody;
20449			var thead     = settings.nTHead;
20450			var tfoot     = settings.nTFoot;
20451			var jqTable   = $(table);
20452			var jqTbody   = $(tbody);
20453			var jqWrapper = $(settings.nTableWrapper);
20454			var rows      = $.map( settings.aoData, function (r) { return r.nTr; } );
20455			var i, ien;
20456	
20457			// Flag to note that the table is currently being destroyed - no action
20458			// should be taken
20459			settings.bDestroying = true;
20460	
20461			// Fire off the destroy callbacks for plug-ins etc
20462			_fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
20463	
20464			// If not being removed from the document, make all columns visible
20465			if ( ! remove ) {
20466				new _Api( settings ).columns().visible( true );
20467			}
20468	
20469			// Blitz all `DT` namespaced events (these are internal events, the
20470			// lowercase, `dt` events are user subscribed and they are responsible
20471			// for removing them
20472			jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
20473			$(window).off('.DT-'+settings.sInstance);
20474	
20475			// When scrolling we had to break the table up - restore it
20476			if ( table != thead.parentNode ) {
20477				jqTable.children('thead').detach();
20478				jqTable.append( thead );
20479			}
20480	
20481			if ( tfoot && table != tfoot.parentNode ) {
20482				jqTable.children('tfoot').detach();
20483				jqTable.append( tfoot );
20484			}
20485	
20486			settings.aaSorting = [];
20487			settings.aaSortingFixed = [];
20488			_fnSortingClasses( settings );
20489	
20490			$( rows ).removeClass( settings.asStripeClasses.join(' ') );
20491	
20492			$('th, td', thead).removeClass( classes.sSortable+' '+
20493				classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
20494			);
20495	
20496			// Add the TR elements back into the table in their original order
20497			jqTbody.children().detach();
20498			jqTbody.append( rows );
20499	
20500			// Remove the DataTables generated nodes, events and classes
20501			var removedMethod = remove ? 'remove' : 'detach';
20502			jqTable[ removedMethod ]();
20503			jqWrapper[ removedMethod ]();
20504	
20505			// If we need to reattach the table to the document
20506			if ( ! remove && orig ) {
20507				// insertBefore acts like appendChild if !arg[1]
20508				orig.insertBefore( table, settings.nTableReinsertBefore );
20509	
20510				// Restore the width of the original table - was read from the style property,
20511				// so we can restore directly to that
20512				jqTable
20513					.css( 'width', settings.sDestroyWidth )
20514					.removeClass( classes.sTable );
20515	
20516				// If the were originally stripe classes - then we add them back here.
20517				// Note this is not fool proof (for example if not all rows had stripe
20518				// classes - but it's a good effort without getting carried away
20519				ien = settings.asDestroyStripes.length;
20520	
20521				if ( ien ) {
20522					jqTbody.children().each( function (i) {
20523						$(this).addClass( settings.asDestroyStripes[i % ien] );
20524					} );
20525				}
20526			}
20527	
20528			/* Remove the settings object from the settings array */
20529			var idx = $.inArray( settings, DataTable.settings );
20530			if ( idx !== -1 ) {
20531				DataTable.settings.splice( idx, 1 );
20532			}
20533		} );
20534	} );
20535	
20536	
20537	// Add the `every()` method for rows, columns and cells in a compact form
20538	$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
20539		_api_register( type+'s().every()', function ( fn ) {
20540			var opts = this.selector.opts;
20541			var api = this;
20542	
20543			return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
20544				// Rows and columns:
20545				//  arg1 - index
20546				//  arg2 - table counter
20547				//  arg3 - loop counter
20548				//  arg4 - undefined
20549				// Cells:
20550				//  arg1 - row index
20551				//  arg2 - column index
20552				//  arg3 - table counter
20553				//  arg4 - loop counter
20554				fn.call(
20555					api[ type ](
20556						arg1,
20557						type==='cell' ? arg2 : opts,
20558						type==='cell' ? opts : undefined
20559					),
20560					arg1, arg2, arg3, arg4
20561				);
20562			} );
20563		} );
20564	} );
20565	
20566	
20567	// i18n method for extensions to be able to use the language object from the
20568	// DataTable
20569	_api_register( 'i18n()', function ( token, def, plural ) {
20570		var ctx = this.context[0];
20571		var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
20572	
20573		if ( resolved === undefined ) {
20574			resolved = def;
20575		}
20576	
20577		if ( plural !== undefined && $.isPlainObject( resolved ) ) {
20578			resolved = resolved[ plural ] !== undefined ?
20579				resolved[ plural ] :
20580				resolved._;
20581		}
20582	
20583		return resolved.replace( '%d', plural ); // nb: plural might be undefined,
20584	} );
20585	/**
20586	 * Version string for plug-ins to check compatibility. Allowed format is
20587	 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
20588	 * only for non-release builds. See http://semver.org/ for more information.
20589	 *  @member
20590	 *  @type string
20591	 *  @default Version number
20592	 */
20593	DataTable.version = "1.11.3";
20594
20595	/**
20596	 * Private data store, containing all of the settings objects that are
20597	 * created for the tables on a given page.
20598	 *
20599	 * Note that the `DataTable.settings` object is aliased to
20600	 * `jQuery.fn.dataTableExt` through which it may be accessed and
20601	 * manipulated, or `jQuery.fn.dataTable.settings`.
20602	 *  @member
20603	 *  @type array
20604	 *  @default []
20605	 *  @private
20606	 */
20607	DataTable.settings = [];
vendor: 69,697 bytes, lines 20608-22798
20608
20609	/**
20610	 * Object models container, for the various models that DataTables has
20611	 * available to it. These models define the objects that are used to hold
20612	 * the active state and configuration of the table.
20613	 *  @namespace
20614	 */
20615	DataTable.models = {};
20616	
20617	
20618	
20619	/**
20620	 * Template object for the way in which DataTables holds information about
20621	 * search information for the global filter and individual column filters.
20622	 *  @namespace
20623	 */
20624	DataTable.models.oSearch = {
20625		/**
20626		 * Flag to indicate if the filtering should be case insensitive or not
20627		 *  @type boolean
20628		 *  @default true
20629		 */
20630		"bCaseInsensitive": true,
20631	
20632		/**
20633		 * Applied search term
20634		 *  @type string
20635		 *  @default <i>Empty string</i>
20636		 */
20637		"sSearch": "",
20638	
20639		/**
20640		 * Flag to indicate if the search term should be interpreted as a
20641		 * regular expression (true) or not (false) and therefore and special
20642		 * regex characters escaped.
20643		 *  @type boolean
20644		 *  @default false
20645		 */
20646		"bRegex": false,
20647	
20648		/**
20649		 * Flag to indicate if DataTables is to use its smart filtering or not.
20650		 *  @type boolean
20651		 *  @default true
20652		 */
20653		"bSmart": true,
20654	
20655		/**
20656		 * Flag to indicate if DataTables should only trigger a search when
20657		 * the return key is pressed.
20658		 *  @type boolean
20659		 *  @default false
20660		 */
20661		"return": false
20662	};
20663	
20664	
20665	
20666	
20667	/**
20668	 * Template object for the way in which DataTables holds information about
20669	 * each individual row. This is the object format used for the settings
20670	 * aoData array.
20671	 *  @namespace
20672	 */
20673	DataTable.models.oRow = {
20674		/**
20675		 * TR element for the row
20676		 *  @type node
20677		 *  @default null
20678		 */
20679		"nTr": null,
20680	
20681		/**
20682		 * Array of TD elements for each row. This is null until the row has been
20683		 * created.
20684		 *  @type array nodes
20685		 *  @default []
20686		 */
20687		"anCells": null,
20688	
20689		/**
20690		 * Data object from the original data source for the row. This is either
20691		 * an array if using the traditional form of DataTables, or an object if
20692		 * using mData options. The exact type will depend on the passed in
20693		 * data from the data source, or will be an array if using DOM a data
20694		 * source.
20695		 *  @type array|object
20696		 *  @default []
20697		 */
20698		"_aData": [],
20699	
20700		/**
20701		 * Sorting data cache - this array is ostensibly the same length as the
20702		 * number of columns (although each index is generated only as it is
20703		 * needed), and holds the data that is used for sorting each column in the
20704		 * row. We do this cache generation at the start of the sort in order that
20705		 * the formatting of the sort data need be done only once for each cell
20706		 * per sort. This array should not be read from or written to by anything
20707		 * other than the master sorting methods.
20708		 *  @type array
20709		 *  @default null
20710		 *  @private
20711		 */
20712		"_aSortData": null,
20713	
20714		/**
20715		 * Per cell filtering data cache. As per the sort data cache, used to
20716		 * increase the performance of the filtering in DataTables
20717		 *  @type array
20718		 *  @default null
20719		 *  @private
20720		 */
20721		"_aFilterData": null,
20722	
20723		/**
20724		 * Filtering data cache. This is the same as the cell filtering cache, but
20725		 * in this case a string rather than an array. This is easily computed with
20726		 * a join on `_aFilterData`, but is provided as a cache so the join isn't
20727		 * needed on every search (memory traded for performance)
20728		 *  @type array
20729		 *  @default null
20730		 *  @private
20731		 */
20732		"_sFilterRow": null,
20733	
20734		/**
20735		 * Cache of the class name that DataTables has applied to the row, so we
20736		 * can quickly look at this variable rather than needing to do a DOM check
20737		 * on className for the nTr property.
20738		 *  @type string
20739		 *  @default <i>Empty string</i>
20740		 *  @private
20741		 */
20742		"_sRowStripe": "",
20743	
20744		/**
20745		 * Denote if the original data source was from the DOM, or the data source
20746		 * object. This is used for invalidating data, so DataTables can
20747		 * automatically read data from the original source, unless uninstructed
20748		 * otherwise.
20749		 *  @type string
20750		 *  @default null
20751		 *  @private
20752		 */
20753		"src": null,
20754	
20755		/**
20756		 * Index in the aoData array. This saves an indexOf lookup when we have the
20757		 * object, but want to know the index
20758		 *  @type integer
20759		 *  @default -1
20760		 *  @private
20761		 */
20762		"idx": -1
20763	};
20764	
20765	
20766	/**
20767	 * Template object for the column information object in DataTables. This object
20768	 * is held in the settings aoColumns array and contains all the information that
20769	 * DataTables needs about each individual column.
20770	 *
20771	 * Note that this object is related to {@link DataTable.defaults.column}
20772	 * but this one is the internal data store for DataTables's cache of columns.
20773	 * It should NOT be manipulated outside of DataTables. Any configuration should
20774	 * be done through the initialisation options.
20775	 *  @namespace
20776	 */
20777	DataTable.models.oColumn = {
20778		/**
20779		 * Column index. This could be worked out on-the-fly with $.inArray, but it
20780		 * is faster to just hold it as a variable
20781		 *  @type integer
20782		 *  @default null
20783		 */
20784		"idx": null,
20785	
20786		/**
20787		 * A list of the columns that sorting should occur on when this column
20788		 * is sorted. That this property is an array allows multi-column sorting
20789		 * to be defined for a column (for example first name / last name columns
20790		 * would benefit from this). The values are integers pointing to the
20791		 * columns to be sorted on (typically it will be a single integer pointing
20792		 * at itself, but that doesn't need to be the case).
20793		 *  @type array
20794		 */
20795		"aDataSort": null,
20796	
20797		/**
20798		 * Define the sorting directions that are applied to the column, in sequence
20799		 * as the column is repeatedly sorted upon - i.e. the first value is used
20800		 * as the sorting direction when the column if first sorted (clicked on).
20801		 * Sort it again (click again) and it will move on to the next index.
20802		 * Repeat until loop.
20803		 *  @type array
20804		 */
20805		"asSorting": null,
20806	
20807		/**
20808		 * Flag to indicate if the column is searchable, and thus should be included
20809		 * in the filtering or not.
20810		 *  @type boolean
20811		 */
20812		"bSearchable": null,
20813	
20814		/**
20815		 * Flag to indicate if the column is sortable or not.
20816		 *  @type boolean
20817		 */
20818		"bSortable": null,
20819	
20820		/**
20821		 * Flag to indicate if the column is currently visible in the table or not
20822		 *  @type boolean
20823		 */
20824		"bVisible": null,
20825	
20826		/**
20827		 * Store for manual type assignment using the `column.type` option. This
20828		 * is held in store so we can manipulate the column's `sType` property.
20829		 *  @type string
20830		 *  @default null
20831		 *  @private
20832		 */
20833		"_sManualType": null,
20834	
20835		/**
20836		 * Flag to indicate if HTML5 data attributes should be used as the data
20837		 * source for filtering or sorting. True is either are.
20838		 *  @type boolean
20839		 *  @default false
20840		 *  @private
20841		 */
20842		"_bAttrSrc": false,
20843	
20844		/**
20845		 * Developer definable function that is called whenever a cell is created (Ajax source,
20846		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
20847		 * allowing you to modify the DOM element (add background colour for example) when the
20848		 * element is available.
20849		 *  @type function
20850		 *  @param {element} nTd The TD node that has been created
20851		 *  @param {*} sData The Data for the cell
20852		 *  @param {array|object} oData The data for the whole row
20853		 *  @param {int} iRow The row index for the aoData data store
20854		 *  @default null
20855		 */
20856		"fnCreatedCell": null,
20857	
20858		/**
20859		 * Function to get data from a cell in a column. You should <b>never</b>
20860		 * access data directly through _aData internally in DataTables - always use
20861		 * the method attached to this property. It allows mData to function as
20862		 * required. This function is automatically assigned by the column
20863		 * initialisation method
20864		 *  @type function
20865		 *  @param {array|object} oData The data array/object for the array
20866		 *    (i.e. aoData[]._aData)
20867		 *  @param {string} sSpecific The specific data type you want to get -
20868		 *    'display', 'type' 'filter' 'sort'
20869		 *  @returns {*} The data for the cell from the given row's data
20870		 *  @default null
20871		 */
20872		"fnGetData": null,
20873	
20874		/**
20875		 * Function to set data for a cell in the column. You should <b>never</b>
20876		 * set the data directly to _aData internally in DataTables - always use
20877		 * this method. It allows mData to function as required. This function
20878		 * is automatically assigned by the column initialisation method
20879		 *  @type function
20880		 *  @param {array|object} oData The data array/object for the array
20881		 *    (i.e. aoData[]._aData)
20882		 *  @param {*} sValue Value to set
20883		 *  @default null
20884		 */
20885		"fnSetData": null,
20886	
20887		/**
20888		 * Property to read the value for the cells in the column from the data
20889		 * source array / object. If null, then the default content is used, if a
20890		 * function is given then the return from the function is used.
20891		 *  @type function|int|string|null
20892		 *  @default null
20893		 */
20894		"mData": null,
20895	
20896		/**
20897		 * Partner property to mData which is used (only when defined) to get
20898		 * the data - i.e. it is basically the same as mData, but without the
20899		 * 'set' option, and also the data fed to it is the result from mData.
20900		 * This is the rendering method to match the data method of mData.
20901		 *  @type function|int|string|null
20902		 *  @default null
20903		 */
20904		"mRender": null,
20905	
20906		/**
20907		 * Unique header TH/TD element for this column - this is what the sorting
20908		 * listener is attached to (if sorting is enabled.)
20909		 *  @type node
20910		 *  @default null
20911		 */
20912		"nTh": null,
20913	
20914		/**
20915		 * Unique footer TH/TD element for this column (if there is one). Not used
20916		 * in DataTables as such, but can be used for plug-ins to reference the
20917		 * footer for each column.
20918		 *  @type node
20919		 *  @default null
20920		 */
20921		"nTf": null,
20922	
20923		/**
20924		 * The class to apply to all TD elements in the table's TBODY for the column
20925		 *  @type string
20926		 *  @default null
20927		 */
20928		"sClass": null,
20929	
20930		/**
20931		 * When DataTables calculates the column widths to assign to each column,
20932		 * it finds the longest string in each column and then constructs a
20933		 * temporary table and reads the widths from that. The problem with this
20934		 * is that "mmm" is much wider then "iiii", but the latter is a longer
20935		 * string - thus the calculation can go wrong (doing it properly and putting
20936		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
20937		 * a "work around" we provide this option. It will append its value to the
20938		 * text that is found to be the longest string for the column - i.e. padding.
20939		 *  @type string
20940		 */
20941		"sContentPadding": null,
20942	
20943		/**
20944		 * Allows a default value to be given for a column's data, and will be used
20945		 * whenever a null data source is encountered (this can be because mData
20946		 * is set to null, or because the data source itself is null).
20947		 *  @type string
20948		 *  @default null
20949		 */
20950		"sDefaultContent": null,
20951	
20952		/**
20953		 * Name for the column, allowing reference to the column by name as well as
20954		 * by index (needs a lookup to work by name).
20955		 *  @type string
20956		 */
20957		"sName": null,
20958	
20959		/**
20960		 * Custom sorting data type - defines which of the available plug-ins in
20961		 * afnSortData the custom sorting will use - if any is defined.
20962		 *  @type string
20963		 *  @default std
20964		 */
20965		"sSortDataType": 'std',
20966	
20967		/**
20968		 * Class to be applied to the header element when sorting on this column
20969		 *  @type string
20970		 *  @default null
20971		 */
20972		"sSortingClass": null,
20973	
20974		/**
20975		 * Class to be applied to the header element when sorting on this column -
20976		 * when jQuery UI theming is used.
20977		 *  @type string
20978		 *  @default null
20979		 */
20980		"sSortingClassJUI": null,
20981	
20982		/**
20983		 * Title of the column - what is seen in the TH element (nTh).
20984		 *  @type string
20985		 */
20986		"sTitle": null,
20987	
20988		/**
20989		 * Column sorting and filtering type
20990		 *  @type string
20991		 *  @default null
20992		 */
20993		"sType": null,
20994	
20995		/**
20996		 * Width of the column
20997		 *  @type string
20998		 *  @default null
20999		 */
21000		"sWidth": null,
21001	
21002		/**
21003		 * Width of the column when it was first "encountered"
21004		 *  @type string
21005		 *  @default null
21006		 */
21007		"sWidthOrig": null
21008	};
21009	
21010	
21011	/*
21012	 * Developer note: The properties of the object below are given in Hungarian
21013	 * notation, that was used as the interface for DataTables prior to v1.10, however
21014	 * from v1.10 onwards the primary interface is camel case. In order to avoid
21015	 * breaking backwards compatibility utterly with this change, the Hungarian
21016	 * version is still, internally the primary interface, but is is not documented
21017	 * - hence the @name tags in each doc comment. This allows a Javascript function
21018	 * to create a map from Hungarian notation to camel case (going the other direction
21019	 * would require each property to be listed, which would add around 3K to the size
21020	 * of DataTables, while this method is about a 0.5K hit).
21021	 *
21022	 * Ultimately this does pave the way for Hungarian notation to be dropped
21023	 * completely, but that is a massive amount of work and will break current
21024	 * installs (therefore is on-hold until v2).
21025	 */
21026	
21027	/**
21028	 * Initialisation options that can be given to DataTables at initialisation
21029	 * time.
21030	 *  @namespace
21031	 */
21032	DataTable.defaults = {
21033		/**
21034		 * An array of data to use for the table, passed in at initialisation which
21035		 * will be used in preference to any data which is already in the DOM. This is
21036		 * particularly useful for constructing tables purely in Javascript, for
21037		 * example with a custom Ajax call.
21038		 *  @type array
21039		 *  @default null
21040		 *
21041		 *  @dtopt Option
21042		 *  @name DataTable.defaults.data
21043		 *
21044		 *  @example
21045		 *    // Using a 2D array data source
21046		 *    $(document).ready( function () {
21047		 *      $('#example').dataTable( {
21048		 *        "data": [
21049		 *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
21050		 *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
21051		 *        ],
21052		 *        "columns": [
21053		 *          { "title": "Engine" },
21054		 *          { "title": "Browser" },
21055		 *          { "title": "Platform" },
21056		 *          { "title": "Version" },
21057		 *          { "title": "Grade" }
21058		 *        ]
21059		 *      } );
21060		 *    } );
21061		 *
21062		 *  @example
21063		 *    // Using an array of objects as a data source (`data`)
21064		 *    $(document).ready( function () {
21065		 *      $('#example').dataTable( {
21066		 *        "data": [
21067		 *          {
21068		 *            "engine":   "Trident",
21069		 *            "browser":  "Internet Explorer 4.0",
21070		 *            "platform": "Win 95+",
21071		 *            "version":  4,
21072		 *            "grade":    "X"
21073		 *          },
21074		 *          {
21075		 *            "engine":   "Trident",
21076		 *            "browser":  "Internet Explorer 5.0",
21077		 *            "platform": "Win 95+",
21078		 *            "version":  5,
21079		 *            "grade":    "C"
21080		 *          }
21081		 *        ],
21082		 *        "columns": [
21083		 *          { "title": "Engine",   "data": "engine" },
21084		 *          { "title": "Browser",  "data": "browser" },
21085		 *          { "title": "Platform", "data": "platform" },
21086		 *          { "title": "Version",  "data": "version" },
21087		 *          { "title": "Grade",    "data": "grade" }
21088		 *        ]
21089		 *      } );
21090		 *    } );
21091		 */
21092		"aaData": null,
21093	
21094	
21095		/**
21096		 * If ordering is enabled, then DataTables will perform a first pass sort on
21097		 * initialisation. You can define which column(s) the sort is performed
21098		 * upon, and the sorting direction, with this variable. The `sorting` array
21099		 * should contain an array for each column to be sorted initially containing
21100		 * the column's index and a direction string ('asc' or 'desc').
21101		 *  @type array
21102		 *  @default [[0,'asc']]
21103		 *
21104		 *  @dtopt Option
21105		 *  @name DataTable.defaults.order
21106		 *
21107		 *  @example
21108		 *    // Sort by 3rd column first, and then 4th column
21109		 *    $(document).ready( function() {
21110		 *      $('#example').dataTable( {
21111		 *        "order": [[2,'asc'], [3,'desc']]
21112		 *      } );
21113		 *    } );
21114		 *
21115		 *    // No initial sorting
21116		 *    $(document).ready( function() {
21117		 *      $('#example').dataTable( {
21118		 *        "order": []
21119		 *      } );
21120		 *    } );
21121		 */
21122		"aaSorting": [[0,'asc']],
21123	
21124	
21125		/**
21126		 * This parameter is basically identical to the `sorting` parameter, but
21127		 * cannot be overridden by user interaction with the table. What this means
21128		 * is that you could have a column (visible or hidden) which the sorting
21129		 * will always be forced on first - any sorting after that (from the user)
21130		 * will then be performed as required. This can be useful for grouping rows
21131		 * together.
21132		 *  @type array
21133		 *  @default null
21134		 *
21135		 *  @dtopt Option
21136		 *  @name DataTable.defaults.orderFixed
21137		 *
21138		 *  @example
21139		 *    $(document).ready( function() {
21140		 *      $('#example').dataTable( {
21141		 *        "orderFixed": [[0,'asc']]
21142		 *      } );
21143		 *    } )
21144		 */
21145		"aaSortingFixed": [],
21146	
21147	
21148		/**
21149		 * DataTables can be instructed to load data to display in the table from a
21150		 * Ajax source. This option defines how that Ajax call is made and where to.
21151		 *
21152		 * The `ajax` property has three different modes of operation, depending on
21153		 * how it is defined. These are:
21154		 *
21155		 * * `string` - Set the URL from where the data should be loaded from.
21156		 * * `object` - Define properties for `jQuery.ajax`.
21157		 * * `function` - Custom data get function
21158		 *
21159		 * `string`
21160		 * --------
21161		 *
21162		 * As a string, the `ajax` property simply defines the URL from which
21163		 * DataTables will load data.
21164		 *
21165		 * `object`
21166		 * --------
21167		 *
21168		 * As an object, the parameters in the object are passed to
21169		 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
21170		 * of the Ajax request. DataTables has a number of default parameters which
21171		 * you can override using this option. Please refer to the jQuery
21172		 * documentation for a full description of the options available, although
21173		 * the following parameters provide additional options in DataTables or
21174		 * require special consideration:
21175		 *
21176		 * * `data` - As with jQuery, `data` can be provided as an object, but it
21177		 *   can also be used as a function to manipulate the data DataTables sends
21178		 *   to the server. The function takes a single parameter, an object of
21179		 *   parameters with the values that DataTables has readied for sending. An
21180		 *   object may be returned which will be merged into the DataTables
21181		 *   defaults, or you can add the items to the object that was passed in and
21182		 *   not return anything from the function. This supersedes `fnServerParams`
21183		 *   from DataTables 1.9-.
21184		 *
21185		 * * `dataSrc` - By default DataTables will look for the property `data` (or
21186		 *   `aaData` for compatibility with DataTables 1.9-) when obtaining data
21187		 *   from an Ajax source or for server-side processing - this parameter
21188		 *   allows that property to be changed. You can use Javascript dotted
21189		 *   object notation to get a data source for multiple levels of nesting, or
21190		 *   it my be used as a function. As a function it takes a single parameter,
21191		 *   the JSON returned from the server, which can be manipulated as
21192		 *   required, with the returned value being that used by DataTables as the
21193		 *   data source for the table. This supersedes `sAjaxDataProp` from
21194		 *   DataTables 1.9-.
21195		 *
21196		 * * `success` - Should not be overridden it is used internally in
21197		 *   DataTables. To manipulate / transform the data returned by the server
21198		 *   use `ajax.dataSrc`, or use `ajax` as a function (see below).
21199		 *
21200		 * `function`
21201		 * ----------
21202		 *
21203		 * As a function, making the Ajax call is left up to yourself allowing
21204		 * complete control of the Ajax request. Indeed, if desired, a method other
21205		 * than Ajax could be used to obtain the required data, such as Web storage
21206		 * or an AIR database.
21207		 *
21208		 * The function is given four parameters and no return is required. The
21209		 * parameters are:
21210		 *
21211		 * 1. _object_ - Data to send to the server
21212		 * 2. _function_ - Callback function that must be executed when the required
21213		 *    data has been obtained. That data should be passed into the callback
21214		 *    as the only parameter
21215		 * 3. _object_ - DataTables settings object for the table
21216		 *
21217		 * Note that this supersedes `fnServerData` from DataTables 1.9-.
21218		 *
21219		 *  @type string|object|function
21220		 *  @default null
21221		 *
21222		 *  @dtopt Option
21223		 *  @name DataTable.defaults.ajax
21224		 *  @since 1.10.0
21225		 *
21226		 * @example
21227		 *   // Get JSON data from a file via Ajax.
21228		 *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
21229		 *   $('#example').dataTable( {
21230		 *     "ajax": "data.json"
21231		 *   } );
21232		 *
21233		 * @example
21234		 *   // Get JSON data from a file via Ajax, using `dataSrc` to change
21235		 *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
21236		 *   $('#example').dataTable( {
21237		 *     "ajax": {
21238		 *       "url": "data.json",
21239		 *       "dataSrc": "tableData"
21240		 *     }
21241		 *   } );
21242		 *
21243		 * @example
21244		 *   // Get JSON data from a file via Ajax, using `dataSrc` to read data
21245		 *   // from a plain array rather than an array in an object
21246		 *   $('#example').dataTable( {
21247		 *     "ajax": {
21248		 *       "url": "data.json",
21249		 *       "dataSrc": ""
21250		 *     }
21251		 *   } );
21252		 *
21253		 * @example
21254		 *   // Manipulate the data returned from the server - add a link to data
21255		 *   // (note this can, should, be done using `render` for the column - this
21256		 *   // is just a simple example of how the data can be manipulated).
21257		 *   $('#example').dataTable( {
21258		 *     "ajax": {
21259		 *       "url": "data.json",
21260		 *       "dataSrc": function ( json ) {
21261		 *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {
21262		 *           json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
21263		 *         }
21264		 *         return json;
21265		 *       }
21266		 *     }
21267		 *   } );
21268		 *
21269		 * @example
21270		 *   // Add data to the request
21271		 *   $('#example').dataTable( {
21272		 *     "ajax": {
21273		 *       "url": "data.json",
21274		 *       "data": function ( d ) {
21275		 *         return {
21276		 *           "extra_search": $('#extra').val()
21277		 *         };
21278		 *       }
21279		 *     }
21280		 *   } );
21281		 *
21282		 * @example
21283		 *   // Send request as POST
21284		 *   $('#example').dataTable( {
21285		 *     "ajax": {
21286		 *       "url": "data.json",
21287		 *       "type": "POST"
21288		 *     }
21289		 *   } );
21290		 *
21291		 * @example
21292		 *   // Get the data from localStorage (could interface with a form for
21293		 *   // adding, editing and removing rows).
21294		 *   $('#example').dataTable( {
21295		 *     "ajax": function (data, callback, settings) {
21296		 *       callback(
21297		 *         JSON.parse( localStorage.getItem('dataTablesData') )
21298		 *       );
21299		 *     }
21300		 *   } );
21301		 */
21302		"ajax": null,
21303	
21304	
21305		/**
21306		 * This parameter allows you to readily specify the entries in the length drop
21307		 * down menu that DataTables shows when pagination is enabled. It can be
21308		 * either a 1D array of options which will be used for both the displayed
21309		 * option and the value, or a 2D array which will use the array in the first
21310		 * position as the value, and the array in the second position as the
21311		 * displayed options (useful for language strings such as 'All').
21312		 *
21313		 * Note that the `pageLength` property will be automatically set to the
21314		 * first value given in this array, unless `pageLength` is also provided.
21315		 *  @type array
21316		 *  @default [ 10, 25, 50, 100 ]
21317		 *
21318		 *  @dtopt Option
21319		 *  @name DataTable.defaults.lengthMenu
21320		 *
21321		 *  @example
21322		 *    $(document).ready( function() {
21323		 *      $('#example').dataTable( {
21324		 *        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
21325		 *      } );
21326		 *    } );
21327		 */
21328		"aLengthMenu": [ 10, 25, 50, 100 ],
21329	
21330	
21331		/**
21332		 * The `columns` option in the initialisation parameter allows you to define
21333		 * details about the way individual columns behave. For a full list of
21334		 * column options that can be set, please see
21335		 * {@link DataTable.defaults.column}. Note that if you use `columns` to
21336		 * define your columns, you must have an entry in the array for every single
21337		 * column that you have in your table (these can be null if you don't which
21338		 * to specify any options).
21339		 *  @member
21340		 *
21341		 *  @name DataTable.defaults.column
21342		 */
21343		"aoColumns": null,
21344	
21345		/**
21346		 * Very similar to `columns`, `columnDefs` allows you to target a specific
21347		 * column, multiple columns, or all columns, using the `targets` property of
21348		 * each object in the array. This allows great flexibility when creating
21349		 * tables, as the `columnDefs` arrays can be of any length, targeting the
21350		 * columns you specifically want. `columnDefs` may use any of the column
21351		 * options available: {@link DataTable.defaults.column}, but it _must_
21352		 * have `targets` defined in each object in the array. Values in the `targets`
21353		 * array may be:
21354		 *   <ul>
21355		 *     <li>a string - class name will be matched on the TH for the column</li>
21356		 *     <li>0 or a positive integer - column index counting from the left</li>
21357		 *     <li>a negative integer - column index counting from the right</li>
21358		 *     <li>the string "_all" - all columns (i.e. assign a default)</li>
21359		 *   </ul>
21360		 *  @member
21361		 *
21362		 *  @name DataTable.defaults.columnDefs
21363		 */
21364		"aoColumnDefs": null,
21365	
21366	
21367		/**
21368		 * Basically the same as `search`, this parameter defines the individual column
21369		 * filtering state at initialisation time. The array must be of the same size
21370		 * as the number of columns, and each element be an object with the parameters
21371		 * `search` and `escapeRegex` (the latter is optional). 'null' is also
21372		 * accepted and the default will be used.
21373		 *  @type array
21374		 *  @default []
21375		 *
21376		 *  @dtopt Option
21377		 *  @name DataTable.defaults.searchCols
21378		 *
21379		 *  @example
21380		 *    $(document).ready( function() {
21381		 *      $('#example').dataTable( {
21382		 *        "searchCols": [
21383		 *          null,
21384		 *          { "search": "My filter" },
21385		 *          null,
21386		 *          { "search": "^[0-9]", "escapeRegex": false }
21387		 *        ]
21388		 *      } );
21389		 *    } )
21390		 */
21391		"aoSearchCols": [],
21392	
21393	
21394		/**
21395		 * An array of CSS classes that should be applied to displayed rows. This
21396		 * array may be of any length, and DataTables will apply each class
21397		 * sequentially, looping when required.
21398		 *  @type array
21399		 *  @default null <i>Will take the values determined by the `oClasses.stripe*`
21400		 *    options</i>
21401		 *
21402		 *  @dtopt Option
21403		 *  @name DataTable.defaults.stripeClasses
21404		 *
21405		 *  @example
21406		 *    $(document).ready( function() {
21407		 *      $('#example').dataTable( {
21408		 *        "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
21409		 *      } );
21410		 *    } )
21411		 */
21412		"asStripeClasses": null,
21413	
21414	
21415		/**
21416		 * Enable or disable automatic column width calculation. This can be disabled
21417		 * as an optimisation (it takes some time to calculate the widths) if the
21418		 * tables widths are passed in using `columns`.
21419		 *  @type boolean
21420		 *  @default true
21421		 *
21422		 *  @dtopt Features
21423		 *  @name DataTable.defaults.autoWidth
21424		 *
21425		 *  @example
21426		 *    $(document).ready( function () {
21427		 *      $('#example').dataTable( {
21428		 *        "autoWidth": false
21429		 *      } );
21430		 *    } );
21431		 */
21432		"bAutoWidth": true,
21433	
21434	
21435		/**
21436		 * Deferred rendering can provide DataTables with a huge speed boost when you
21437		 * are using an Ajax or JS data source for the table. This option, when set to
21438		 * true, will cause DataTables to defer the creation of the table elements for
21439		 * each row until they are needed for a draw - saving a significant amount of
21440		 * time.
21441		 *  @type boolean
21442		 *  @default false
21443		 *
21444		 *  @dtopt Features
21445		 *  @name DataTable.defaults.deferRender
21446		 *
21447		 *  @example
21448		 *    $(document).ready( function() {
21449		 *      $('#example').dataTable( {
21450		 *        "ajax": "sources/arrays.txt",
21451		 *        "deferRender": true
21452		 *      } );
21453		 *    } );
21454		 */
21455		"bDeferRender": false,
21456	
21457	
21458		/**
21459		 * Replace a DataTable which matches the given selector and replace it with
21460		 * one which has the properties of the new initialisation object passed. If no
21461		 * table matches the selector, then the new DataTable will be constructed as
21462		 * per normal.
21463		 *  @type boolean
21464		 *  @default false
21465		 *
21466		 *  @dtopt Options
21467		 *  @name DataTable.defaults.destroy
21468		 *
21469		 *  @example
21470		 *    $(document).ready( function() {
21471		 *      $('#example').dataTable( {
21472		 *        "srollY": "200px",
21473		 *        "paginate": false
21474		 *      } );
21475		 *
21476		 *      // Some time later....
21477		 *      $('#example').dataTable( {
21478		 *        "filter": false,
21479		 *        "destroy": true
21480		 *      } );
21481		 *    } );
21482		 */
21483		"bDestroy": false,
21484	
21485	
21486		/**
21487		 * Enable or disable filtering of data. Filtering in DataTables is "smart" in
21488		 * that it allows the end user to input multiple words (space separated) and
21489		 * will match a row containing those words, even if not in the order that was
21490		 * specified (this allow matching across multiple columns). Note that if you
21491		 * wish to use filtering in DataTables this must remain 'true' - to remove the
21492		 * default filtering input box and retain filtering abilities, please use
21493		 * {@link DataTable.defaults.dom}.
21494		 *  @type boolean
21495		 *  @default true
21496		 *
21497		 *  @dtopt Features
21498		 *  @name DataTable.defaults.searching
21499		 *
21500		 *  @example
21501		 *    $(document).ready( function () {
21502		 *      $('#example').dataTable( {
21503		 *        "searching": false
21504		 *      } );
21505		 *    } );
21506		 */
21507		"bFilter": true,
21508	
21509	
21510		/**
21511		 * Enable or disable the table information display. This shows information
21512		 * about the data that is currently visible on the page, including information
21513		 * about filtered data if that action is being performed.
21514		 *  @type boolean
21515		 *  @default true
21516		 *
21517		 *  @dtopt Features
21518		 *  @name DataTable.defaults.info
21519		 *
21520		 *  @example
21521		 *    $(document).ready( function () {
21522		 *      $('#example').dataTable( {
21523		 *        "info": false
21524		 *      } );
21525		 *    } );
21526		 */
21527		"bInfo": true,
21528	
21529	
21530		/**
21531		 * Allows the end user to select the size of a formatted page from a select
21532		 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
21533		 *  @type boolean
21534		 *  @default true
21535		 *
21536		 *  @dtopt Features
21537		 *  @name DataTable.defaults.lengthChange
21538		 *
21539		 *  @example
21540		 *    $(document).ready( function () {
21541		 *      $('#example').dataTable( {
21542		 *        "lengthChange": false
21543		 *      } );
21544		 *    } );
21545		 */
21546		"bLengthChange": true,
21547	
21548	
21549		/**
21550		 * Enable or disable pagination.
21551		 *  @type boolean
21552		 *  @default true
21553		 *
21554		 *  @dtopt Features
21555		 *  @name DataTable.defaults.paging
21556		 *
21557		 *  @example
21558		 *    $(document).ready( function () {
21559		 *      $('#example').dataTable( {
21560		 *        "paging": false
21561		 *      } );
21562		 *    } );
21563		 */
21564		"bPaginate": true,
21565	
21566	
21567		/**
21568		 * Enable or disable the display of a 'processing' indicator when the table is
21569		 * being processed (e.g. a sort). This is particularly useful for tables with
21570		 * large amounts of data where it can take a noticeable amount of time to sort
21571		 * the entries.
21572		 *  @type boolean
21573		 *  @default false
21574		 *
21575		 *  @dtopt Features
21576		 *  @name DataTable.defaults.processing
21577		 *
21578		 *  @example
21579		 *    $(document).ready( function () {
21580		 *      $('#example').dataTable( {
21581		 *        "processing": true
21582		 *      } );
21583		 *    } );
21584		 */
21585		"bProcessing": false,
21586	
21587	
21588		/**
21589		 * Retrieve the DataTables object for the given selector. Note that if the
21590		 * table has already been initialised, this parameter will cause DataTables
21591		 * to simply return the object that has already been set up - it will not take
21592		 * account of any changes you might have made to the initialisation object
21593		 * passed to DataTables (setting this parameter to true is an acknowledgement
21594		 * that you understand this). `destroy` can be used to reinitialise a table if
21595		 * you need.
21596		 *  @type boolean
21597		 *  @default false
21598		 *
21599		 *  @dtopt Options
21600		 *  @name DataTable.defaults.retrieve
21601		 *
21602		 *  @example
21603		 *    $(document).ready( function() {
21604		 *      initTable();
21605		 *      tableActions();
21606		 *    } );
21607		 *
21608		 *    function initTable ()
21609		 *    {
21610		 *      return $('#example').dataTable( {
21611		 *        "scrollY": "200px",
21612		 *        "paginate": false,
21613		 *        "retrieve": true
21614		 *      } );
21615		 *    }
21616		 *
21617		 *    function tableActions ()
21618		 *    {
21619		 *      var table = initTable();
21620		 *      // perform API operations with oTable
21621		 *    }
21622		 */
21623		"bRetrieve": false,
21624	
21625	
21626		/**
21627		 * When vertical (y) scrolling is enabled, DataTables will force the height of
21628		 * the table's viewport to the given height at all times (useful for layout).
21629		 * However, this can look odd when filtering data down to a small data set,
21630		 * and the footer is left "floating" further down. This parameter (when
21631		 * enabled) will cause DataTables to collapse the table's viewport down when
21632		 * the result set will fit within the given Y height.
21633		 *  @type boolean
21634		 *  @default false
21635		 *
21636		 *  @dtopt Options
21637		 *  @name DataTable.defaults.scrollCollapse
21638		 *
21639		 *  @example
21640		 *    $(document).ready( function() {
21641		 *      $('#example').dataTable( {
21642		 *        "scrollY": "200",
21643		 *        "scrollCollapse": true
21644		 *      } );
21645		 *    } );
21646		 */
21647		"bScrollCollapse": false,
21648	
21649	
21650		/**
21651		 * Configure DataTables to use server-side processing. Note that the
21652		 * `ajax` parameter must also be given in order to give DataTables a
21653		 * source to obtain the required data for each draw.
21654		 *  @type boolean
21655		 *  @default false
21656		 *
21657		 *  @dtopt Features
21658		 *  @dtopt Server-side
21659		 *  @name DataTable.defaults.serverSide
21660		 *
21661		 *  @example
21662		 *    $(document).ready( function () {
21663		 *      $('#example').dataTable( {
21664		 *        "serverSide": true,
21665		 *        "ajax": "xhr.php"
21666		 *      } );
21667		 *    } );
21668		 */
21669		"bServerSide": false,
21670	
21671	
21672		/**
21673		 * Enable or disable sorting of columns. Sorting of individual columns can be
21674		 * disabled by the `sortable` option for each column.
21675		 *  @type boolean
21676		 *  @default true
21677		 *
21678		 *  @dtopt Features
21679		 *  @name DataTable.defaults.ordering
21680		 *
21681		 *  @example
21682		 *    $(document).ready( function () {
21683		 *      $('#example').dataTable( {
21684		 *        "ordering": false
21685		 *      } );
21686		 *    } );
21687		 */
21688		"bSort": true,
21689	
21690	
21691		/**
21692		 * Enable or display DataTables' ability to sort multiple columns at the
21693		 * same time (activated by shift-click by the user).
21694		 *  @type boolean
21695		 *  @default true
21696		 *
21697		 *  @dtopt Options
21698		 *  @name DataTable.defaults.orderMulti
21699		 *
21700		 *  @example
21701		 *    // Disable multiple column sorting ability
21702		 *    $(document).ready( function () {
21703		 *      $('#example').dataTable( {
21704		 *        "orderMulti": false
21705		 *      } );
21706		 *    } );
21707		 */
21708		"bSortMulti": true,
21709	
21710	
21711		/**
21712		 * Allows control over whether DataTables should use the top (true) unique
21713		 * cell that is found for a single column, or the bottom (false - default).
21714		 * This is useful when using complex headers.
21715		 *  @type boolean
21716		 *  @default false
21717		 *
21718		 *  @dtopt Options
21719		 *  @name DataTable.defaults.orderCellsTop
21720		 *
21721		 *  @example
21722		 *    $(document).ready( function() {
21723		 *      $('#example').dataTable( {
21724		 *        "orderCellsTop": true
21725		 *      } );
21726		 *    } );
21727		 */
21728		"bSortCellsTop": false,
21729	
21730	
21731		/**
21732		 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
21733		 * `sorting\_3` to the columns which are currently being sorted on. This is
21734		 * presented as a feature switch as it can increase processing time (while
21735		 * classes are removed and added) so for large data sets you might want to
21736		 * turn this off.
21737		 *  @type boolean
21738		 *  @default true
21739		 *
21740		 *  @dtopt Features
21741		 *  @name DataTable.defaults.orderClasses
21742		 *
21743		 *  @example
21744		 *    $(document).ready( function () {
21745		 *      $('#example').dataTable( {
21746		 *        "orderClasses": false
21747		 *      } );
21748		 *    } );
21749		 */
21750		"bSortClasses": true,
21751	
21752	
21753		/**
21754		 * Enable or disable state saving. When enabled HTML5 `localStorage` will be
21755		 * used to save table display information such as pagination information,
21756		 * display length, filtering and sorting. As such when the end user reloads
21757		 * the page the display display will match what thy had previously set up.
21758		 *
21759		 * Due to the use of `localStorage` the default state saving is not supported
21760		 * in IE6 or 7. If state saving is required in those browsers, use
21761		 * `stateSaveCallback` to provide a storage solution such as cookies.
21762		 *  @type boolean
21763		 *  @default false
21764		 *
21765		 *  @dtopt Features
21766		 *  @name DataTable.defaults.stateSave
21767		 *
21768		 *  @example
21769		 *    $(document).ready( function () {
21770		 *      $('#example').dataTable( {
21771		 *        "stateSave": true
21772		 *      } );
21773		 *    } );
21774		 */
21775		"bStateSave": false,
21776	
21777	
21778		/**
21779		 * This function is called when a TR element is created (and all TD child
21780		 * elements have been inserted), or registered if using a DOM source, allowing
21781		 * manipulation of the TR element (adding classes etc).
21782		 *  @type function
21783		 *  @param {node} row "TR" element for the current row
21784		 *  @param {array} data Raw data array for this row
21785		 *  @param {int} dataIndex The index of this row in the internal aoData array
21786		 *
21787		 *  @dtopt Callbacks
21788		 *  @name DataTable.defaults.createdRow
21789		 *
21790		 *  @example
21791		 *    $(document).ready( function() {
21792		 *      $('#example').dataTable( {
21793		 *        "createdRow": function( row, data, dataIndex ) {
21794		 *          // Bold the grade for all 'A' grade browsers
21795		 *          if ( data[4] == "A" )
21796		 *          {
21797		 *            $('td:eq(4)', row).html( '<b>A</b>' );
21798		 *          }
21799		 *        }
21800		 *      } );
21801		 *    } );
21802		 */
21803		"fnCreatedRow": null,
21804	
21805	
21806		/**
21807		 * This function is called on every 'draw' event, and allows you to
21808		 * dynamically modify any aspect you want about the created DOM.
21809		 *  @type function
21810		 *  @param {object} settings DataTables settings object
21811		 *
21812		 *  @dtopt Callbacks
21813		 *  @name DataTable.defaults.drawCallback
21814		 *
21815		 *  @example
21816		 *    $(document).ready( function() {
21817		 *      $('#example').dataTable( {
21818		 *        "drawCallback": function( settings ) {
21819		 *          alert( 'DataTables has redrawn the table' );
21820		 *        }
21821		 *      } );
21822		 *    } );
21823		 */
21824		"fnDrawCallback": null,
21825	
21826	
21827		/**
21828		 * Identical to fnHeaderCallback() but for the table footer this function
21829		 * allows you to modify the table footer on every 'draw' event.
21830		 *  @type function
21831		 *  @param {node} foot "TR" element for the footer
21832		 *  @param {array} data Full table data (as derived from the original HTML)
21833		 *  @param {int} start Index for the current display starting point in the
21834		 *    display array
21835		 *  @param {int} end Index for the current display ending point in the
21836		 *    display array
21837		 *  @param {array int} display Index array to translate the visual position
21838		 *    to the full data array
21839		 *
21840		 *  @dtopt Callbacks
21841		 *  @name DataTable.defaults.footerCallback
21842		 *
21843		 *  @example
21844		 *    $(document).ready( function() {
21845		 *      $('#example').dataTable( {
21846		 *        "footerCallback": function( tfoot, data, start, end, display ) {
21847		 *          tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
21848		 *        }
21849		 *      } );
21850		 *    } )
21851		 */
21852		"fnFooterCallback": null,
21853	
21854	
21855		/**
21856		 * When rendering large numbers in the information element for the table
21857		 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
21858		 * to have a comma separator for the 'thousands' units (e.g. 1 million is
21859		 * rendered as "1,000,000") to help readability for the end user. This
21860		 * function will override the default method DataTables uses.
21861		 *  @type function
21862		 *  @member
21863		 *  @param {int} toFormat number to be formatted
21864		 *  @returns {string} formatted string for DataTables to show the number
21865		 *
21866		 *  @dtopt Callbacks
21867		 *  @name DataTable.defaults.formatNumber
21868		 *
21869		 *  @example
21870		 *    // Format a number using a single quote for the separator (note that
21871		 *    // this can also be done with the language.thousands option)
21872		 *    $(document).ready( function() {
21873		 *      $('#example').dataTable( {
21874		 *        "formatNumber": function ( toFormat ) {
21875		 *          return toFormat.toString().replace(
21876		 *            /\B(?=(\d{3})+(?!\d))/g, "'"
21877		 *          );
21878		 *        };
21879		 *      } );
21880		 *    } );
21881		 */
21882		"fnFormatNumber": function ( toFormat ) {
21883			return toFormat.toString().replace(
21884				/\B(?=(\d{3})+(?!\d))/g,
21885				this.oLanguage.sThousands
21886			);
21887		},
21888	
21889	
21890		/**
21891		 * This function is called on every 'draw' event, and allows you to
21892		 * dynamically modify the header row. This can be used to calculate and
21893		 * display useful information about the table.
21894		 *  @type function
21895		 *  @param {node} head "TR" element for the header
21896		 *  @param {array} data Full table data (as derived from the original HTML)
21897		 *  @param {int} start Index for the current display starting point in the
21898		 *    display array
21899		 *  @param {int} end Index for the current display ending point in the
21900		 *    display array
21901		 *  @param {array int} display Index array to translate the visual position
21902		 *    to the full data array
21903		 *
21904		 *  @dtopt Callbacks
21905		 *  @name DataTable.defaults.headerCallback
21906		 *
21907		 *  @example
21908		 *    $(document).ready( function() {
21909		 *      $('#example').dataTable( {
21910		 *        "fheaderCallback": function( head, data, start, end, display ) {
21911		 *          head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
21912		 *        }
21913		 *      } );
21914		 *    } )
21915		 */
21916		"fnHeaderCallback": null,
21917	
21918	
21919		/**
21920		 * The information element can be used to convey information about the current
21921		 * state of the table. Although the internationalisation options presented by
21922		 * DataTables are quite capable of dealing with most customisations, there may
21923		 * be times where you wish to customise the string further. This callback
21924		 * allows you to do exactly that.
21925		 *  @type function
21926		 *  @param {object} oSettings DataTables settings object
21927		 *  @param {int} start Starting position in data for the draw
21928		 *  @param {int} end End position in data for the draw
21929		 *  @param {int} max Total number of rows in the table (regardless of
21930		 *    filtering)
21931		 *  @param {int} total Total number of rows in the data set, after filtering
21932		 *  @param {string} pre The string that DataTables has formatted using it's
21933		 *    own rules
21934		 *  @returns {string} The string to be displayed in the information element.
21935		 *
21936		 *  @dtopt Callbacks
21937		 *  @name DataTable.defaults.infoCallback
21938		 *
21939		 *  @example
21940		 *    $('#example').dataTable( {
21941		 *      "infoCallback": function( settings, start, end, max, total, pre ) {
21942		 *        return start +" to "+ end;
21943		 *      }
21944		 *    } );
21945		 */
21946		"fnInfoCallback": null,
21947	
21948	
21949		/**
21950		 * Called when the table has been initialised. Normally DataTables will
21951		 * initialise sequentially and there will be no need for this function,
21952		 * however, this does not hold true when using external language information
21953		 * since that is obtained using an async XHR call.
21954		 *  @type function
21955		 *  @param {object} settings DataTables settings object
21956		 *  @param {object} json The JSON object request from the server - only
21957		 *    present if client-side Ajax sourced data is used
21958		 *
21959		 *  @dtopt Callbacks
21960		 *  @name DataTable.defaults.initComplete
21961		 *
21962		 *  @example
21963		 *    $(document).ready( function() {
21964		 *      $('#example').dataTable( {
21965		 *        "initComplete": function(settings, json) {
21966		 *          alert( 'DataTables has finished its initialisation.' );
21967		 *        }
21968		 *      } );
21969		 *    } )
21970		 */
21971		"fnInitComplete": null,
21972	
21973	
21974		/**
21975		 * Called at the very start of each table draw and can be used to cancel the
21976		 * draw by returning false, any other return (including undefined) results in
21977		 * the full draw occurring).
21978		 *  @type function
21979		 *  @param {object} settings DataTables settings object
21980		 *  @returns {boolean} False will cancel the draw, anything else (including no
21981		 *    return) will allow it to complete.
21982		 *
21983		 *  @dtopt Callbacks
21984		 *  @name DataTable.defaults.preDrawCallback
21985		 *
21986		 *  @example
21987		 *    $(document).ready( function() {
21988		 *      $('#example').dataTable( {
21989		 *        "preDrawCallback": function( settings ) {
21990		 *          if ( $('#test').val() == 1 ) {
21991		 *            return false;
21992		 *          }
21993		 *        }
21994		 *      } );
21995		 *    } );
21996		 */
21997		"fnPreDrawCallback": null,
21998	
21999	
22000		/**
22001		 * This function allows you to 'post process' each row after it have been
22002		 * generated for each table draw, but before it is rendered on screen. This
22003		 * function might be used for setting the row class name etc.
22004		 *  @type function
22005		 *  @param {node} row "TR" element for the current row
22006		 *  @param {array} data Raw data array for this row
22007		 *  @param {int} displayIndex The display index for the current table draw
22008		 *  @param {int} displayIndexFull The index of the data in the full list of
22009		 *    rows (after filtering)
22010		 *
22011		 *  @dtopt Callbacks
22012		 *  @name DataTable.defaults.rowCallback
22013		 *
22014		 *  @example
22015		 *    $(document).ready( function() {
22016		 *      $('#example').dataTable( {
22017		 *        "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
22018		 *          // Bold the grade for all 'A' grade browsers
22019		 *          if ( data[4] == "A" ) {
22020		 *            $('td:eq(4)', row).html( '<b>A</b>' );
22021		 *          }
22022		 *        }
22023		 *      } );
22024		 *    } );
22025		 */
22026		"fnRowCallback": null,
22027	
22028	
22029		/**
22030		 * __Deprecated__ The functionality provided by this parameter has now been
22031		 * superseded by that provided through `ajax`, which should be used instead.
22032		 *
22033		 * This parameter allows you to override the default function which obtains
22034		 * the data from the server so something more suitable for your application.
22035		 * For example you could use POST data, or pull information from a Gears or
22036		 * AIR database.
22037		 *  @type function
22038		 *  @member
22039		 *  @param {string} source HTTP source to obtain the data from (`ajax`)
22040		 *  @param {array} data A key/value pair object containing the data to send
22041		 *    to the server
22042		 *  @param {function} callback to be called on completion of the data get
22043		 *    process that will draw the data on the page.
22044		 *  @param {object} settings DataTables settings object
22045		 *
22046		 *  @dtopt Callbacks
22047		 *  @dtopt Server-side
22048		 *  @name DataTable.defaults.serverData
22049		 *
22050		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
22051		 */
22052		"fnServerData": null,
22053	
22054	
22055		/**
22056		 * __Deprecated__ The functionality provided by this parameter has now been
22057		 * superseded by that provided through `ajax`, which should be used instead.
22058		 *
22059		 *  It is often useful to send extra data to the server when making an Ajax
22060		 * request - for example custom filtering information, and this callback
22061		 * function makes it trivial to send extra information to the server. The
22062		 * passed in parameter is the data set that has been constructed by
22063		 * DataTables, and you can add to this or modify it as you require.
22064		 *  @type function
22065		 *  @param {array} data Data array (array of objects which are name/value
22066		 *    pairs) that has been constructed by DataTables and will be sent to the
22067		 *    server. In the case of Ajax sourced data with server-side processing
22068		 *    this will be an empty array, for server-side processing there will be a
22069		 *    significant number of parameters!
22070		 *  @returns {undefined} Ensure that you modify the data array passed in,
22071		 *    as this is passed by reference.
22072		 *
22073		 *  @dtopt Callbacks
22074		 *  @dtopt Server-side
22075		 *  @name DataTable.defaults.serverParams
22076		 *
22077		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
22078		 */
22079		"fnServerParams": null,
22080	
22081	
22082		/**
22083		 * Load the table state. With this function you can define from where, and how, the
22084		 * state of a table is loaded. By default DataTables will load from `localStorage`
22085		 * but you might wish to use a server-side database or cookies.
22086		 *  @type function
22087		 *  @member
22088		 *  @param {object} settings DataTables settings object
22089		 *  @param {object} callback Callback that can be executed when done. It
22090		 *    should be passed the loaded state object.
22091		 *  @return {object} The DataTables state object to be loaded
22092		 *
22093		 *  @dtopt Callbacks
22094		 *  @name DataTable.defaults.stateLoadCallback
22095		 *
22096		 *  @example
22097		 *    $(document).ready( function() {
22098		 *      $('#example').dataTable( {
22099		 *        "stateSave": true,
22100		 *        "stateLoadCallback": function (settings, callback) {
22101		 *          $.ajax( {
22102		 *            "url": "/state_load",
22103		 *            "dataType": "json",
22104		 *            "success": function (json) {
22105		 *              callback( json );
22106		 *            }
22107		 *          } );
22108		 *        }
22109		 *      } );
22110		 *    } );
22111		 */
22112		"fnStateLoadCallback": function ( settings ) {
22113			try {
22114				return JSON.parse(
22115					(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
22116						'DataTables_'+settings.sInstance+'_'+location.pathname
22117					)
22118				);
22119			} catch (e) {
22120				return {};
22121			}
22122		},
22123	
22124	
22125		/**
22126		 * Callback which allows modification of the saved state prior to loading that state.
22127		 * This callback is called when the table is loading state from the stored data, but
22128		 * prior to the settings object being modified by the saved state. Note that for
22129		 * plug-in authors, you should use the `stateLoadParams` event to load parameters for
22130		 * a plug-in.
22131		 *  @type function
22132		 *  @param {object} settings DataTables settings object
22133		 *  @param {object} data The state object that is to be loaded
22134		 *
22135		 *  @dtopt Callbacks
22136		 *  @name DataTable.defaults.stateLoadParams
22137		 *
22138		 *  @example
22139		 *    // Remove a saved filter, so filtering is never loaded
22140		 *    $(document).ready( function() {
22141		 *      $('#example').dataTable( {
22142		 *        "stateSave": true,
22143		 *        "stateLoadParams": function (settings, data) {
22144		 *          data.oSearch.sSearch = "";
22145		 *        }
22146		 *      } );
22147		 *    } );
22148		 *
22149		 *  @example
22150		 *    // Disallow state loading by returning false
22151		 *    $(document).ready( function() {
22152		 *      $('#example').dataTable( {
22153		 *        "stateSave": true,
22154		 *        "stateLoadParams": function (settings, data) {
22155		 *          return false;
22156		 *        }
22157		 *      } );
22158		 *    } );
22159		 */
22160		"fnStateLoadParams": null,
22161	
22162	
22163		/**
22164		 * Callback that is called when the state has been loaded from the state saving method
22165		 * and the DataTables settings object has been modified as a result of the loaded state.
22166		 *  @type function
22167		 *  @param {object} settings DataTables settings object
22168		 *  @param {object} data The state object that was loaded
22169		 *
22170		 *  @dtopt Callbacks
22171		 *  @name DataTable.defaults.stateLoaded
22172		 *
22173		 *  @example
22174		 *    // Show an alert with the filtering value that was saved
22175		 *    $(document).ready( function() {
22176		 *      $('#example').dataTable( {
22177		 *        "stateSave": true,
22178		 *        "stateLoaded": function (settings, data) {
22179		 *          alert( 'Saved filter was: '+data.oSearch.sSearch );
22180		 *        }
22181		 *      } );
22182		 *    } );
22183		 */
22184		"fnStateLoaded": null,
22185	
22186	
22187		/**
22188		 * Save the table state. This function allows you to define where and how the state
22189		 * information for the table is stored By default DataTables will use `localStorage`
22190		 * but you might wish to use a server-side database or cookies.
22191		 *  @type function
22192		 *  @member
22193		 *  @param {object} settings DataTables settings object
22194		 *  @param {object} data The state object to be saved
22195		 *
22196		 *  @dtopt Callbacks
22197		 *  @name DataTable.defaults.stateSaveCallback
22198		 *
22199		 *  @example
22200		 *    $(document).ready( function() {
22201		 *      $('#example').dataTable( {
22202		 *        "stateSave": true,
22203		 *        "stateSaveCallback": function (settings, data) {
22204		 *          // Send an Ajax request to the server with the state object
22205		 *          $.ajax( {
22206		 *            "url": "/state_save",
22207		 *            "data": data,
22208		 *            "dataType": "json",
22209		 *            "method": "POST"
22210		 *            "success": function () {}
22211		 *          } );
22212		 *        }
22213		 *      } );
22214		 *    } );
22215		 */
22216		"fnStateSaveCallback": function ( settings, data ) {
22217			try {
22218				(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
22219					'DataTables_'+settings.sInstance+'_'+location.pathname,
22220					JSON.stringify( data )
22221				);
22222			} catch (e) {}
22223		},
22224	
22225	
22226		/**
22227		 * Callback which allows modification of the state to be saved. Called when the table
22228		 * has changed state a new state save is required. This method allows modification of
22229		 * the state saving object prior to actually doing the save, including addition or
22230		 * other state properties or modification. Note that for plug-in authors, you should
22231		 * use the `stateSaveParams` event to save parameters for a plug-in.
22232		 *  @type function
22233		 *  @param {object} settings DataTables settings object
22234		 *  @param {object} data The state object to be saved
22235		 *
22236		 *  @dtopt Callbacks
22237		 *  @name DataTable.defaults.stateSaveParams
22238		 *
22239		 *  @example
22240		 *    // Remove a saved filter, so filtering is never saved
22241		 *    $(document).ready( function() {
22242		 *      $('#example').dataTable( {
22243		 *        "stateSave": true,
22244		 *        "stateSaveParams": function (settings, data) {
22245		 *          data.oSearch.sSearch = "";
22246		 *        }
22247		 *      } );
22248		 *    } );
22249		 */
22250		"fnStateSaveParams": null,
22251	
22252	
22253		/**
22254		 * Duration for which the saved state information is considered valid. After this period
22255		 * has elapsed the state will be returned to the default.
22256		 * Value is given in seconds.
22257		 *  @type int
22258		 *  @default 7200 <i>(2 hours)</i>
22259		 *
22260		 *  @dtopt Options
22261		 *  @name DataTable.defaults.stateDuration
22262		 *
22263		 *  @example
22264		 *    $(document).ready( function() {
22265		 *      $('#example').dataTable( {
22266		 *        "stateDuration": 60*60*24; // 1 day
22267		 *      } );
22268		 *    } )
22269		 */
22270		"iStateDuration": 7200,
22271	
22272	
22273		/**
22274		 * When enabled DataTables will not make a request to the server for the first
22275		 * page draw - rather it will use the data already on the page (no sorting etc
22276		 * will be applied to it), thus saving on an XHR at load time. `deferLoading`
22277		 * is used to indicate that deferred loading is required, but it is also used
22278		 * to tell DataTables how many records there are in the full table (allowing
22279		 * the information element and pagination to be displayed correctly). In the case
22280		 * where a filtering is applied to the table on initial load, this can be
22281		 * indicated by giving the parameter as an array, where the first element is
22282		 * the number of records available after filtering and the second element is the
22283		 * number of records without filtering (allowing the table information element
22284		 * to be shown correctly).
22285		 *  @type int | array
22286		 *  @default null
22287		 *
22288		 *  @dtopt Options
22289		 *  @name DataTable.defaults.deferLoading
22290		 *
22291		 *  @example
22292		 *    // 57 records available in the table, no filtering applied
22293		 *    $(document).ready( function() {
22294		 *      $('#example').dataTable( {
22295		 *        "serverSide": true,
22296		 *        "ajax": "scripts/server_processing.php",
22297		 *        "deferLoading": 57
22298		 *      } );
22299		 *    } );
22300		 *
22301		 *  @example
22302		 *    // 57 records after filtering, 100 without filtering (an initial filter applied)
22303		 *    $(document).ready( function() {
22304		 *      $('#example').dataTable( {
22305		 *        "serverSide": true,
22306		 *        "ajax": "scripts/server_processing.php",
22307		 *        "deferLoading": [ 57, 100 ],
22308		 *        "search": {
22309		 *          "search": "my_filter"
22310		 *        }
22311		 *      } );
22312		 *    } );
22313		 */
22314		"iDeferLoading": null,
22315	
22316	
22317		/**
22318		 * Number of rows to display on a single page when using pagination. If
22319		 * feature enabled (`lengthChange`) then the end user will be able to override
22320		 * this to a custom setting using a pop-up menu.
22321		 *  @type int
22322		 *  @default 10
22323		 *
22324		 *  @dtopt Options
22325		 *  @name DataTable.defaults.pageLength
22326		 *
22327		 *  @example
22328		 *    $(document).ready( function() {
22329		 *      $('#example').dataTable( {
22330		 *        "pageLength": 50
22331		 *      } );
22332		 *    } )
22333		 */
22334		"iDisplayLength": 10,
22335	
22336	
22337		/**
22338		 * Define the starting point for data display when using DataTables with
22339		 * pagination. Note that this parameter is the number of records, rather than
22340		 * the page number, so if you have 10 records per page and want to start on
22341		 * the third page, it should be "20".
22342		 *  @type int
22343		 *  @default 0
22344		 *
22345		 *  @dtopt Options
22346		 *  @name DataTable.defaults.displayStart
22347		 *
22348		 *  @example
22349		 *    $(document).ready( function() {
22350		 *      $('#example').dataTable( {
22351		 *        "displayStart": 20
22352		 *      } );
22353		 *    } )
22354		 */
22355		"iDisplayStart": 0,
22356	
22357	
22358		/**
22359		 * By default DataTables allows keyboard navigation of the table (sorting, paging,
22360		 * and filtering) by adding a `tabindex` attribute to the required elements. This
22361		 * allows you to tab through the controls and press the enter key to activate them.
22362		 * The tabindex is default 0, meaning that the tab follows the flow of the document.
22363		 * You can overrule this using this parameter if you wish. Use a value of -1 to
22364		 * disable built-in keyboard navigation.
22365		 *  @type int
22366		 *  @default 0
22367		 *
22368		 *  @dtopt Options
22369		 *  @name DataTable.defaults.tabIndex
22370		 *
22371		 *  @example
22372		 *    $(document).ready( function() {
22373		 *      $('#example').dataTable( {
22374		 *        "tabIndex": 1
22375		 *      } );
22376		 *    } );
22377		 */
22378		"iTabIndex": 0,
22379	
22380	
22381		/**
22382		 * Classes that DataTables assigns to the various components and features
22383		 * that it adds to the HTML table. This allows classes to be configured
22384		 * during initialisation in addition to through the static
22385		 * {@link DataTable.ext.oStdClasses} object).
22386		 *  @namespace
22387		 *  @name DataTable.defaults.classes
22388		 */
22389		"oClasses": {},
22390	
22391	
22392		/**
22393		 * All strings that DataTables uses in the user interface that it creates
22394		 * are defined in this object, allowing you to modified them individually or
22395		 * completely replace them all as required.
22396		 *  @namespace
22397		 *  @name DataTable.defaults.language
22398		 */
22399		"oLanguage": {
22400			/**
22401			 * Strings that are used for WAI-ARIA labels and controls only (these are not
22402			 * actually visible on the page, but will be read by screenreaders, and thus
22403			 * must be internationalised as well).
22404			 *  @namespace
22405			 *  @name DataTable.defaults.language.aria
22406			 */
22407			"oAria": {
22408				/**
22409				 * ARIA label that is added to the table headers when the column may be
22410				 * sorted ascending by activing the column (click or return when focused).
22411				 * Note that the column header is prefixed to this string.
22412				 *  @type string
22413				 *  @default : activate to sort column ascending
22414				 *
22415				 *  @dtopt Language
22416				 *  @name DataTable.defaults.language.aria.sortAscending
22417				 *
22418				 *  @example
22419				 *    $(document).ready( function() {
22420				 *      $('#example').dataTable( {
22421				 *        "language": {
22422				 *          "aria": {
22423				 *            "sortAscending": " - click/return to sort ascending"
22424				 *          }
22425				 *        }
22426				 *      } );
22427				 *    } );
22428				 */
22429				"sSortAscending": ": activate to sort column ascending",
22430	
22431				/**
22432				 * ARIA label that is added to the table headers when the column may be
22433				 * sorted descending by activing the column (click or return when focused).
22434				 * Note that the column header is prefixed to this string.
22435				 *  @type string
22436				 *  @default : activate to sort column ascending
22437				 *
22438				 *  @dtopt Language
22439				 *  @name DataTable.defaults.language.aria.sortDescending
22440				 *
22441				 *  @example
22442				 *    $(document).ready( function() {
22443				 *      $('#example').dataTable( {
22444				 *        "language": {
22445				 *          "aria": {
22446				 *            "sortDescending": " - click/return to sort descending"
22447				 *          }
22448				 *        }
22449				 *      } );
22450				 *    } );
22451				 */
22452				"sSortDescending": ": activate to sort column descending"
22453			},
22454	
22455			/**
22456			 * Pagination string used by DataTables for the built-in pagination
22457			 * control types.
22458			 *  @namespace
22459			 *  @name DataTable.defaults.language.paginate
22460			 */
22461			"oPaginate": {
22462				/**
22463				 * Text to use when using the 'full_numbers' type of pagination for the
22464				 * button to take the user to the first page.
22465				 *  @type string
22466				 *  @default First
22467				 *
22468				 *  @dtopt Language
22469				 *  @name DataTable.defaults.language.paginate.first
22470				 *
22471				 *  @example
22472				 *    $(document).ready( function() {
22473				 *      $('#example').dataTable( {
22474				 *        "language": {
22475				 *          "paginate": {
22476				 *            "first": "First page"
22477				 *          }
22478				 *        }
22479				 *      } );
22480				 *    } );
22481				 */
22482				"sFirst": "First",
22483	
22484	
22485				/**
22486				 * Text to use when using the 'full_numbers' type of pagination for the
22487				 * button to take the user to the last page.
22488				 *  @type string
22489				 *  @default Last
22490				 *
22491				 *  @dtopt Language
22492				 *  @name DataTable.defaults.language.paginate.last
22493				 *
22494				 *  @example
22495				 *    $(document).ready( function() {
22496				 *      $('#example').dataTable( {
22497				 *        "language": {
22498				 *          "paginate": {
22499				 *            "last": "Last page"
22500				 *          }
22501				 *        }
22502				 *      } );
22503				 *    } );
22504				 */
22505				"sLast": "Last",
22506	
22507	
22508				/**
22509				 * Text to use for the 'next' pagination button (to take the user to the
22510				 * next page).
22511				 *  @type string
22512				 *  @default Next
22513				 *
22514				 *  @dtopt Language
22515				 *  @name DataTable.defaults.language.paginate.next
22516				 *
22517				 *  @example
22518				 *    $(document).ready( function() {
22519				 *      $('#example').dataTable( {
22520				 *        "language": {
22521				 *          "paginate": {
22522				 *            "next": "Next page"
22523				 *          }
22524				 *        }
22525				 *      } );
22526				 *    } );
22527				 */
22528				"sNext": "Next",
22529	
22530	
22531				/**
22532				 * Text to use for the 'previous' pagination button (to take the user to
22533				 * the previous page).
22534				 *  @type string
22535				 *  @default Previous
22536				 *
22537				 *  @dtopt Language
22538				 *  @name DataTable.defaults.language.paginate.previous
22539				 *
22540				 *  @example
22541				 *    $(document).ready( function() {
22542				 *      $('#example').dataTable( {
22543				 *        "language": {
22544				 *          "paginate": {
22545				 *            "previous": "Previous page"
22546				 *          }
22547				 *        }
22548				 *      } );
22549				 *    } );
22550				 */
22551				"sPrevious": "Previous"
22552			},
22553	
22554			/**
22555			 * This string is shown in preference to `zeroRecords` when the table is
22556			 * empty of data (regardless of filtering). Note that this is an optional
22557			 * parameter - if it is not given, the value of `zeroRecords` will be used
22558			 * instead (either the default or given value).
22559			 *  @type string
22560			 *  @default No data available in table
22561			 *
22562			 *  @dtopt Language
22563			 *  @name DataTable.defaults.language.emptyTable
22564			 *
22565			 *  @example
22566			 *    $(document).ready( function() {
22567			 *      $('#example').dataTable( {
22568			 *        "language": {
22569			 *          "emptyTable": "No data available in table"
22570			 *        }
22571			 *      } );
22572			 *    } );
22573			 */
22574			"sEmptyTable": "No data available in table",
22575	
22576	
22577			/**
22578			 * This string gives information to the end user about the information
22579			 * that is current on display on the page. The following tokens can be
22580			 * used in the string and will be dynamically replaced as the table
22581			 * display updates. This tokens can be placed anywhere in the string, or
22582			 * removed as needed by the language requires:
22583			 *
22584			 * * `\_START\_` - Display index of the first record on the current page
22585			 * * `\_END\_` - Display index of the last record on the current page
22586			 * * `\_TOTAL\_` - Number of records in the table after filtering
22587			 * * `\_MAX\_` - Number of records in the table without filtering
22588			 * * `\_PAGE\_` - Current page number
22589			 * * `\_PAGES\_` - Total number of pages of data in the table
22590			 *
22591			 *  @type string
22592			 *  @default Showing _START_ to _END_ of _TOTAL_ entries
22593			 *
22594			 *  @dtopt Language
22595			 *  @name DataTable.defaults.language.info
22596			 *
22597			 *  @example
22598			 *    $(document).ready( function() {
22599			 *      $('#example').dataTable( {
22600			 *        "language": {
22601			 *          "info": "Showing page _PAGE_ of _PAGES_"
22602			 *        }
22603			 *      } );
22604			 *    } );
22605			 */
22606			"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
22607	
22608	
22609			/**
22610			 * Display information string for when the table is empty. Typically the
22611			 * format of this string should match `info`.
22612			 *  @type string
22613			 *  @default Showing 0 to 0 of 0 entries
22614			 *
22615			 *  @dtopt Language
22616			 *  @name DataTable.defaults.language.infoEmpty
22617			 *
22618			 *  @example
22619			 *    $(document).ready( function() {
22620			 *      $('#example').dataTable( {
22621			 *        "language": {
22622			 *          "infoEmpty": "No entries to show"
22623			 *        }
22624			 *      } );
22625			 *    } );
22626			 */
22627			"sInfoEmpty": "Showing 0 to 0 of 0 entries",
22628	
22629	
22630			/**
22631			 * When a user filters the information in a table, this string is appended
22632			 * to the information (`info`) to give an idea of how strong the filtering
22633			 * is. The variable _MAX_ is dynamically updated.
22634			 *  @type string
22635			 *  @default (filtered from _MAX_ total entries)
22636			 *
22637			 *  @dtopt Language
22638			 *  @name DataTable.defaults.language.infoFiltered
22639			 *
22640			 *  @example
22641			 *    $(document).ready( function() {
22642			 *      $('#example').dataTable( {
22643			 *        "language": {
22644			 *          "infoFiltered": " - filtering from _MAX_ records"
22645			 *        }
22646			 *      } );
22647			 *    } );
22648			 */
22649			"sInfoFiltered": "(filtered from _MAX_ total entries)",
22650	
22651	
22652			/**
22653			 * If can be useful to append extra information to the info string at times,
22654			 * and this variable does exactly that. This information will be appended to
22655			 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
22656			 * being used) at all times.
22657			 *  @type string
22658			 *  @default <i>Empty string</i>
22659			 *
22660			 *  @dtopt Language
22661			 *  @name DataTable.defaults.language.infoPostFix
22662			 *
22663			 *  @example
22664			 *    $(document).ready( function() {
22665			 *      $('#example').dataTable( {
22666			 *        "language": {
22667			 *          "infoPostFix": "All records shown are derived from real information."
22668			 *        }
22669			 *      } );
22670			 *    } );
22671			 */
22672			"sInfoPostFix": "",
22673	
22674	
22675			/**
22676			 * This decimal place operator is a little different from the other
22677			 * language options since DataTables doesn't output floating point
22678			 * numbers, so it won't ever use this for display of a number. Rather,
22679			 * what this parameter does is modify the sort methods of the table so
22680			 * that numbers which are in a format which has a character other than
22681			 * a period (`.`) as a decimal place will be sorted numerically.
22682			 *
22683			 * Note that numbers with different decimal places cannot be shown in
22684			 * the same table and still be sortable, the table must be consistent.
22685			 * However, multiple different tables on the page can use different
22686			 * decimal place characters.
22687			 *  @type string
22688			 *  @default 
22689			 *
22690			 *  @dtopt Language
22691			 *  @name DataTable.defaults.language.decimal
22692			 *
22693			 *  @example
22694			 *    $(document).ready( function() {
22695			 *      $('#example').dataTable( {
22696			 *        "language": {
22697			 *          "decimal": ","
22698			 *          "thousands": "."
22699			 *        }
22700			 *      } );
22701			 *    } );
22702			 */
22703			"sDecimal": "",
22704	
22705	
22706			/**
22707			 * DataTables has a build in number formatter (`formatNumber`) which is
22708			 * used to format large numbers that are used in the table information.
22709			 * By default a comma is used, but this can be trivially changed to any
22710			 * character you wish with this parameter.
22711			 *  @type string
22712			 *  @default ,
22713			 *
22714			 *  @dtopt Language
22715			 *  @name DataTable.defaults.language.thousands
22716			 *
22717			 *  @example
22718			 *    $(document).ready( function() {
22719			 *      $('#example').dataTable( {
22720			 *        "language": {
22721			 *          "thousands": "'"
22722			 *        }
22723			 *      } );
22724			 *    } );
22725			 */
22726			"sThousands": ",",
22727	
22728	
22729			/**
22730			 * Detail the action that will be taken when the drop down menu for the
22731			 * pagination length option is changed. The '_MENU_' variable is replaced
22732			 * with a default select list of 10, 25, 50 and 100, and can be replaced
22733			 * with a custom select box if required.
22734			 *  @type string
22735			 *  @default Show _MENU_ entries
22736			 *
22737			 *  @dtopt Language
22738			 *  @name DataTable.defaults.language.lengthMenu
22739			 *
22740			 *  @example
22741			 *    // Language change only
22742			 *    $(document).ready( function() {
22743			 *      $('#example').dataTable( {
22744			 *        "language": {
22745			 *          "lengthMenu": "Display _MENU_ records"
22746			 *        }
22747			 *      } );
22748			 *    } );
22749			 *
22750			 *  @example
22751			 *    // Language and options change
22752			 *    $(document).ready( function() {
22753			 *      $('#example').dataTable( {
22754			 *        "language": {
22755			 *          "lengthMenu": 'Display <select>'+
22756			 *            '<option value="10">10</option>'+
22757			 *            '<option value="20">20</option>'+
22758			 *            '<option value="30">30</option>'+
22759			 *            '<option value="40">40</option>'+
22760			 *            '<option value="50">50</option>'+
22761			 *            '<option value="-1">All</option>'+
22762			 *            '</select> records'
22763			 *        }
22764			 *      } );
22765			 *    } );
22766			 */
22767			"sLengthMenu": "Show _MENU_ entries",
22768	
22769	
22770			/**
22771			 * When using Ajax sourced data and during the first draw when DataTables is
22772			 * gathering the data, this message is shown in an empty row in the table to
22773			 * indicate to the end user the the data is being loaded. Note that this
22774			 * parameter is not used when loading data by server-side processing, just
22775			 * Ajax sourced data with client-side processing.
22776			 *  @type string
22777			 *  @default Loading...
22778			 *
22779			 *  @dtopt Language
22780			 *  @name DataTable.defaults.language.loadingRecords
22781			 *
22782			 *  @example
22783			 *    $(document).ready( function() {
22784			 *      $('#example').dataTable( {
22785			 *        "language": {
22786			 *          "loadingRecords": "Please wait - loading..."
22787			 *        }
22788			 *      } );
22789			 *    } );
22790			 */
22791			"sLoadingRecords": "Loading...",
22792	
22793	
22794			/**
22795			 * Text which is displayed when the table is processing a user action
22796			 * (usually a sort command or similar).
22797			 *  @type string
22798			 *
22798  @default Processing...
22799			 *
22800			 *  @dtopt Language
22801			 *  @name DataTable.defaults.language.processing
22802			 *
22803			 *  @example
22804			 *    $(document).ready( function() {
22805			 *      $('#example').dataTable( {
22806			 *        "language": {
22807			 *          "processing": "DataTables is currently busy"
22808			 *        }
22809			 *      } );
22810			 *    } );
22811			 */
22812			"sProcessing": "Processing...
vendor: 85,392 bytes, lines 22812-25656
22812",
22813	
22814	
22815			/**
22816			 * Details the actions that will be taken when the user types into the
22817			 * filtering input text box. The variable "_INPUT_", if used in the string,
22818			 * is replaced with the HTML text box for the filtering input allowing
22819			 * control over where it appears in the string. If "_INPUT_" is not given
22820			 * then the input box is appended to the string automatically.
22821			 *  @type string
22822			 *  @default Search:
22823			 *
22824			 *  @dtopt Language
22825			 *  @name DataTable.defaults.language.search
22826			 *
22827			 *  @example
22828			 *    // Input text box will be appended at the end automatically
22829			 *    $(document).ready( function() {
22830			 *      $('#example').dataTable( {
22831			 *        "language": {
22832			 *          "search": "Filter records:"
22833			 *        }
22834			 *      } );
22835			 *    } );
22836			 *
22837			 *  @example
22838			 *    // Specify where the filter should appear
22839			 *    $(document).ready( function() {
22840			 *      $('#example').dataTable( {
22841			 *        "language": {
22842			 *          "search": "Apply filter _INPUT_ to table"
22843			 *        }
22844			 *      } );
22845			 *    } );
22846			 */
22847			"sSearch": "Search:",
22848	
22849	
22850			/**
22851			 * Assign a `placeholder` attribute to the search `input` element
22852			 *  @type string
22853			 *  @default 
22854			 *
22855			 *  @dtopt Language
22856			 *  @name DataTable.defaults.language.searchPlaceholder
22857			 */
22858			"sSearchPlaceholder": "",
22859	
22860	
22861			/**
22862			 * All of the language information can be stored in a file on the
22863			 * server-side, which DataTables will look up if this parameter is passed.
22864			 * It must store the URL of the language file, which is in a JSON format,
22865			 * and the object has the same properties as the oLanguage object in the
22866			 * initialiser object (i.e. the above parameters). Please refer to one of
22867			 * the example language files to see how this works in action.
22868			 *  @type string
22869			 *  @default <i>Empty string - i.e. disabled</i>
22870			 *
22871			 *  @dtopt Language
22872			 *  @name DataTable.defaults.language.url
22873			 *
22874			 *  @example
22875			 *    $(document).ready( function() {
22876			 *      $('#example').dataTable( {
22877			 *        "language": {
22878			 *          "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
22879			 *        }
22880			 *      } );
22881			 *    } );
22882			 */
22883			"sUrl": "",
22884	
22885	
22886			/**
22887			 * Text shown inside the table records when the is no information to be
22888			 * displayed after filtering. `emptyTable` is shown when there is simply no
22889			 * information in the table at all (regardless of filtering).
22890			 *  @type string
22891			 *  @default No matching records found
22892			 *
22893			 *  @dtopt Language
22894			 *  @name DataTable.defaults.language.zeroRecords
22895			 *
22896			 *  @example
22897			 *    $(document).ready( function() {
22898			 *      $('#example').dataTable( {
22899			 *        "language": {
22900			 *          "zeroRecords": "No records to display"
22901			 *        }
22902			 *      } );
22903			 *    } );
22904			 */
22905			"sZeroRecords": "No matching records found"
22906		},
22907	
22908	
22909		/**
22910		 * This parameter allows you to have define the global filtering state at
22911		 * initialisation time. As an object the `search` parameter must be
22912		 * defined, but all other parameters are optional. When `regex` is true,
22913		 * the search string will be treated as a regular expression, when false
22914		 * (default) it will be treated as a straight string. When `smart`
22915		 * DataTables will use it's smart filtering methods (to word match at
22916		 * any point in the data), when false this will not be done.
22917		 *  @namespace
22918		 *  @extends DataTable.models.oSearch
22919		 *
22920		 *  @dtopt Options
22921		 *  @name DataTable.defaults.search
22922		 *
22923		 *  @example
22924		 *    $(document).ready( function() {
22925		 *      $('#example').dataTable( {
22926		 *        "search": {"search": "Initial search"}
22927		 *      } );
22928		 *    } )
22929		 */
22930		"oSearch": $.extend( {}, DataTable.models.oSearch ),
22931	
22932	
22933		/**
22934		 * __Deprecated__ The functionality provided by this parameter has now been
22935		 * superseded by that provided through `ajax`, which should be used instead.
22936		 *
22937		 * By default DataTables will look for the property `data` (or `aaData` for
22938		 * compatibility with DataTables 1.9-) when obtaining data from an Ajax
22939		 * source or for server-side processing - this parameter allows that
22940		 * property to be changed. You can use Javascript dotted object notation to
22941		 * get a data source for multiple levels of nesting.
22942		 *  @type string
22943		 *  @default data
22944		 *
22945		 *  @dtopt Options
22946		 *  @dtopt Server-side
22947		 *  @name DataTable.defaults.ajaxDataProp
22948		 *
22949		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
22950		 */
22951		"sAjaxDataProp": "data",
22952	
22953	
22954		/**
22955		 * __Deprecated__ The functionality provided by this parameter has now been
22956		 * superseded by that provided through `ajax`, which should be used instead.
22957		 *
22958		 * You can instruct DataTables to load data from an external
22959		 * source using this parameter (use aData if you want to pass data in you
22960		 * already have). Simply provide a url a JSON object can be obtained from.
22961		 *  @type string
22962		 *  @default null
22963		 *
22964		 *  @dtopt Options
22965		 *  @dtopt Server-side
22966		 *  @name DataTable.defaults.ajaxSource
22967		 *
22968		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
22969		 */
22970		"sAjaxSource": null,
22971	
22972	
22973		/**
22974		 * This initialisation variable allows you to specify exactly where in the
22975		 * DOM you want DataTables to inject the various controls it adds to the page
22976		 * (for example you might want the pagination controls at the top of the
22977		 * table). DIV elements (with or without a custom class) can also be added to
22978		 * aid styling. The follow syntax is used:
22979		 *   <ul>
22980		 *     <li>The following options are allowed:
22981		 *       <ul>
22982		 *         <li>'l' - Length changing</li>
22983		 *         <li>'f' - Filtering input</li>
22984		 *         <li>'t' - The table!</li>
22985		 *         <li>'i' - Information</li>
22986		 *         <li>'p' - Pagination</li>
22987		 *         <li>'r' - pRocessing</li>
22988		 *       </ul>
22989		 *     </li>
22990		 *     <li>The following constants are allowed:
22991		 *       <ul>
22992		 *         <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
22993		 *         <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
22994		 *       </ul>
22995		 *     </li>
22996		 *     <li>The following syntax is expected:
22997		 *       <ul>
22998		 *         <li>'&lt;' and '&gt;' - div elements</li>
22999		 *         <li>'&lt;"class" and '&gt;' - div with a class</li>
23000		 *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
23001		 *       </ul>
23002		 *     </li>
23003		 *     <li>Examples:
23004		 *       <ul>
23005		 *         <li>'&lt;"wrapper"flipt&gt;'</li>
23006		 *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
23007		 *       </ul>
23008		 *     </li>
23009		 *   </ul>
23010		 *  @type string
23011		 *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
23012		 *    <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
23013		 *
23014		 *  @dtopt Options
23015		 *  @name DataTable.defaults.dom
23016		 *
23017		 *  @example
23018		 *    $(document).ready( function() {
23019		 *      $('#example').dataTable( {
23020		 *        "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
23021		 *      } );
23022		 *    } );
23023		 */
23024		"sDom": "lfrtip",
23025	
23026	
23027		/**
23028		 * Search delay option. This will throttle full table searches that use the
23029		 * DataTables provided search input element (it does not effect calls to
23030		 * `dt-api search()`, providing a delay before the search is made.
23031		 *  @type integer
23032		 *  @default 0
23033		 *
23034		 *  @dtopt Options
23035		 *  @name DataTable.defaults.searchDelay
23036		 *
23037		 *  @example
23038		 *    $(document).ready( function() {
23039		 *      $('#example').dataTable( {
23040		 *        "searchDelay": 200
23041		 *      } );
23042		 *    } )
23043		 */
23044		"searchDelay": null,
23045	
23046	
23047		/**
23048		 * DataTables features six different built-in options for the buttons to
23049		 * display for pagination control:
23050		 *
23051		 * * `numbers` - Page number buttons only
23052		 * * `simple` - 'Previous' and 'Next' buttons only
23053		 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
23054		 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
23055		 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
23056		 * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
23057		 *  
23058		 * Further methods can be added using {@link DataTable.ext.oPagination}.
23059		 *  @type string
23060		 *  @default simple_numbers
23061		 *
23062		 *  @dtopt Options
23063		 *  @name DataTable.defaults.pagingType
23064		 *
23065		 *  @example
23066		 *    $(document).ready( function() {
23067		 *      $('#example').dataTable( {
23068		 *        "pagingType": "full_numbers"
23069		 *      } );
23070		 *    } )
23071		 */
23072		"sPaginationType": "simple_numbers",
23073	
23074	
23075		/**
23076		 * Enable horizontal scrolling. When a table is too wide to fit into a
23077		 * certain layout, or you have a large number of columns in the table, you
23078		 * can enable x-scrolling to show the table in a viewport, which can be
23079		 * scrolled. This property can be `true` which will allow the table to
23080		 * scroll horizontally when needed, or any CSS unit, or a number (in which
23081		 * case it will be treated as a pixel measurement). Setting as simply `true`
23082		 * is recommended.
23083		 *  @type boolean|string
23084		 *  @default <i>blank string - i.e. disabled</i>
23085		 *
23086		 *  @dtopt Features
23087		 *  @name DataTable.defaults.scrollX
23088		 *
23089		 *  @example
23090		 *    $(document).ready( function() {
23091		 *      $('#example').dataTable( {
23092		 *        "scrollX": true,
23093		 *        "scrollCollapse": true
23094		 *      } );
23095		 *    } );
23096		 */
23097		"sScrollX": "",
23098	
23099	
23100		/**
23101		 * This property can be used to force a DataTable to use more width than it
23102		 * might otherwise do when x-scrolling is enabled. For example if you have a
23103		 * table which requires to be well spaced, this parameter is useful for
23104		 * "over-sizing" the table, and thus forcing scrolling. This property can by
23105		 * any CSS unit, or a number (in which case it will be treated as a pixel
23106		 * measurement).
23107		 *  @type string
23108		 *  @default <i>blank string - i.e. disabled</i>
23109		 *
23110		 *  @dtopt Options
23111		 *  @name DataTable.defaults.scrollXInner
23112		 *
23113		 *  @example
23114		 *    $(document).ready( function() {
23115		 *      $('#example').dataTable( {
23116		 *        "scrollX": "100%",
23117		 *        "scrollXInner": "110%"
23118		 *      } );
23119		 *    } );
23120		 */
23121		"sScrollXInner": "",
23122	
23123	
23124		/**
23125		 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
23126		 * to the given height, and enable scrolling for any data which overflows the
23127		 * current viewport. This can be used as an alternative to paging to display
23128		 * a lot of data in a small area (although paging and scrolling can both be
23129		 * enabled at the same time). This property can be any CSS unit, or a number
23130		 * (in which case it will be treated as a pixel measurement).
23131		 *  @type string
23132		 *  @default <i>blank string - i.e. disabled</i>
23133		 *
23134		 *  @dtopt Features
23135		 *  @name DataTable.defaults.scrollY
23136		 *
23137		 *  @example
23138		 *    $(document).ready( function() {
23139		 *      $('#example').dataTable( {
23140		 *        "scrollY": "200px",
23141		 *        "paginate": false
23142		 *      } );
23143		 *    } );
23144		 */
23145		"sScrollY": "",
23146	
23147	
23148		/**
23149		 * __Deprecated__ The functionality provided by this parameter has now been
23150		 * superseded by that provided through `ajax`, which should be used instead.
23151		 *
23152		 * Set the HTTP method that is used to make the Ajax call for server-side
23153		 * processing or Ajax sourced data.
23154		 *  @type string
23155		 *  @default GET
23156		 *
23157		 *  @dtopt Options
23158		 *  @dtopt Server-side
23159		 *  @name DataTable.defaults.serverMethod
23160		 *
23161		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
23162		 */
23163		"sServerMethod": "GET",
23164	
23165	
23166		/**
23167		 * DataTables makes use of renderers when displaying HTML elements for
23168		 * a table. These renderers can be added or modified by plug-ins to
23169		 * generate suitable mark-up for a site. For example the Bootstrap
23170		 * integration plug-in for DataTables uses a paging button renderer to
23171		 * display pagination buttons in the mark-up required by Bootstrap.
23172		 *
23173		 * For further information about the renderers available see
23174		 * DataTable.ext.renderer
23175		 *  @type string|object
23176		 *  @default null
23177		 *
23178		 *  @name DataTable.defaults.renderer
23179		 *
23180		 */
23181		"renderer": null,
23182	
23183	
23184		/**
23185		 * Set the data property name that DataTables should use to get a row's id
23186		 * to set as the `id` property in the node.
23187		 *  @type string
23188		 *  @default DT_RowId
23189		 *
23190		 *  @name DataTable.defaults.rowId
23191		 */
23192		"rowId": "DT_RowId"
23193	};
23194	
23195	_fnHungarianMap( DataTable.defaults );
23196	
23197	
23198	
23199	/*
23200	 * Developer note - See note in model.defaults.js about the use of Hungarian
23201	 * notation and camel case.
23202	 */
23203	
23204	/**
23205	 * Column options that can be given to DataTables at initialisation time.
23206	 *  @namespace
23207	 */
23208	DataTable.defaults.column = {
23209		/**
23210		 * Define which column(s) an order will occur on for this column. This
23211		 * allows a column's ordering to take multiple columns into account when
23212		 * doing a sort or use the data from a different column. For example first
23213		 * name / last name columns make sense to do a multi-column sort over the
23214		 * two columns.
23215		 *  @type array|int
23216		 *  @default null <i>Takes the value of the column index automatically</i>
23217		 *
23218		 *  @name DataTable.defaults.column.orderData
23219		 *  @dtopt Columns
23220		 *
23221		 *  @example
23222		 *    // Using `columnDefs`
23223		 *    $(document).ready( function() {
23224		 *      $('#example').dataTable( {
23225		 *        "columnDefs": [
23226		 *          { "orderData": [ 0, 1 ], "targets": [ 0 ] },
23227		 *          { "orderData": [ 1, 0 ], "targets": [ 1 ] },
23228		 *          { "orderData": 2, "targets": [ 2 ] }
23229		 *        ]
23230		 *      } );
23231		 *    } );
23232		 *
23233		 *  @example
23234		 *    // Using `columns`
23235		 *    $(document).ready( function() {
23236		 *      $('#example').dataTable( {
23237		 *        "columns": [
23238		 *          { "orderData": [ 0, 1 ] },
23239		 *          { "orderData": [ 1, 0 ] },
23240		 *          { "orderData": 2 },
23241		 *          null,
23242		 *          null
23243		 *        ]
23244		 *      } );
23245		 *    } );
23246		 */
23247		"aDataSort": null,
23248		"iDataSort": -1,
23249	
23250	
23251		/**
23252		 * You can control the default ordering direction, and even alter the
23253		 * behaviour of the sort handler (i.e. only allow ascending ordering etc)
23254		 * using this parameter.
23255		 *  @type array
23256		 *  @default [ 'asc', 'desc' ]
23257		 *
23258		 *  @name DataTable.defaults.column.orderSequence
23259		 *  @dtopt Columns
23260		 *
23261		 *  @example
23262		 *    // Using `columnDefs`
23263		 *    $(document).ready( function() {
23264		 *      $('#example').dataTable( {
23265		 *        "columnDefs": [
23266		 *          { "orderSequence": [ "asc" ], "targets": [ 1 ] },
23267		 *          { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
23268		 *          { "orderSequence": [ "desc" ], "targets": [ 3 ] }
23269		 *        ]
23270		 *      } );
23271		 *    } );
23272		 *
23273		 *  @example
23274		 *    // Using `columns`
23275		 *    $(document).ready( function() {
23276		 *      $('#example').dataTable( {
23277		 *        "columns": [
23278		 *          null,
23279		 *          { "orderSequence": [ "asc" ] },
23280		 *          { "orderSequence": [ "desc", "asc", "asc" ] },
23281		 *          { "orderSequence": [ "desc" ] },
23282		 *          null
23283		 *        ]
23284		 *      } );
23285		 *    } );
23286		 */
23287		"asSorting": [ 'asc', 'desc' ],
23288	
23289	
23290		/**
23291		 * Enable or disable filtering on the data in this column.
23292		 *  @type boolean
23293		 *  @default true
23294		 *
23295		 *  @name DataTable.defaults.column.searchable
23296		 *  @dtopt Columns
23297		 *
23298		 *  @example
23299		 *    // Using `columnDefs`
23300		 *    $(document).ready( function() {
23301		 *      $('#example').dataTable( {
23302		 *        "columnDefs": [
23303		 *          { "searchable": false, "targets": [ 0 ] }
23304		 *        ] } );
23305		 *    } );
23306		 *
23307		 *  @example
23308		 *    // Using `columns`
23309		 *    $(document).ready( function() {
23310		 *      $('#example').dataTable( {
23311		 *        "columns": [
23312		 *          { "searchable": false },
23313		 *          null,
23314		 *          null,
23315		 *          null,
23316		 *          null
23317		 *        ] } );
23318		 *    } );
23319		 */
23320		"bSearchable": true,
23321	
23322	
23323		/**
23324		 * Enable or disable ordering on this column.
23325		 *  @type boolean
23326		 *  @default true
23327		 *
23328		 *  @name DataTable.defaults.column.orderable
23329		 *  @dtopt Columns
23330		 *
23331		 *  @example
23332		 *    // Using `columnDefs`
23333		 *    $(document).ready( function() {
23334		 *      $('#example').dataTable( {
23335		 *        "columnDefs": [
23336		 *          { "orderable": false, "targets": [ 0 ] }
23337		 *        ] } );
23338		 *    } );
23339		 *
23340		 *  @example
23341		 *    // Using `columns`
23342		 *    $(document).ready( function() {
23343		 *      $('#example').dataTable( {
23344		 *        "columns": [
23345		 *          { "orderable": false },
23346		 *          null,
23347		 *          null,
23348		 *          null,
23349		 *          null
23350		 *        ] } );
23351		 *    } );
23352		 */
23353		"bSortable": true,
23354	
23355	
23356		/**
23357		 * Enable or disable the display of this column.
23358		 *  @type boolean
23359		 *  @default true
23360		 *
23361		 *  @name DataTable.defaults.column.visible
23362		 *  @dtopt Columns
23363		 *
23364		 *  @example
23365		 *    // Using `columnDefs`
23366		 *    $(document).ready( function() {
23367		 *      $('#example').dataTable( {
23368		 *        "columnDefs": [
23369		 *          { "visible": false, "targets": [ 0 ] }
23370		 *        ] } );
23371		 *    } );
23372		 *
23373		 *  @example
23374		 *    // Using `columns`
23375		 *    $(document).ready( function() {
23376		 *      $('#example').dataTable( {
23377		 *        "columns": [
23378		 *          { "visible": false },
23379		 *          null,
23380		 *          null,
23381		 *          null,
23382		 *          null
23383		 *        ] } );
23384		 *    } );
23385		 */
23386		"bVisible": true,
23387	
23388	
23389		/**
23390		 * Developer definable function that is called whenever a cell is created (Ajax source,
23391		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
23392		 * allowing you to modify the DOM element (add background colour for example) when the
23393		 * element is available.
23394		 *  @type function
23395		 *  @param {element} td The TD node that has been created
23396		 *  @param {*} cellData The Data for the cell
23397		 *  @param {array|object} rowData The data for the whole row
23398		 *  @param {int} row The row index for the aoData data store
23399		 *  @param {int} col The column index for aoColumns
23400		 *
23401		 *  @name DataTable.defaults.column.createdCell
23402		 *  @dtopt Columns
23403		 *
23404		 *  @example
23405		 *    $(document).ready( function() {
23406		 *      $('#example').dataTable( {
23407		 *        "columnDefs": [ {
23408		 *          "targets": [3],
23409		 *          "createdCell": function (td, cellData, rowData, row, col) {
23410		 *            if ( cellData == "1.7" ) {
23411		 *              $(td).css('color', 'blue')
23412		 *            }
23413		 *          }
23414		 *        } ]
23415		 *      });
23416		 *    } );
23417		 */
23418		"fnCreatedCell": null,
23419	
23420	
23421		/**
23422		 * This parameter has been replaced by `data` in DataTables to ensure naming
23423		 * consistency. `dataProp` can still be used, as there is backwards
23424		 * compatibility in DataTables for this option, but it is strongly
23425		 * recommended that you use `data` in preference to `dataProp`.
23426		 *  @name DataTable.defaults.column.dataProp
23427		 */
23428	
23429	
23430		/**
23431		 * This property can be used to read data from any data source property,
23432		 * including deeply nested objects / properties. `data` can be given in a
23433		 * number of different ways which effect its behaviour:
23434		 *
23435		 * * `integer` - treated as an array index for the data source. This is the
23436		 *   default that DataTables uses (incrementally increased for each column).
23437		 * * `string` - read an object property from the data source. There are
23438		 *   three 'special' options that can be used in the string to alter how
23439		 *   DataTables reads the data from the source object:
23440		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
23441		 *      Javascript to read from nested objects, so to can the options
23442		 *      specified in `data`. For example: `browser.version` or
23443		 *      `browser.name`. If your object parameter name contains a period, use
23444		 *      `\\` to escape it - i.e. `first\\.name`.
23445		 *    * `[]` - Array notation. DataTables can automatically combine data
23446		 *      from and array source, joining the data with the characters provided
23447		 *      between the two brackets. For example: `name[, ]` would provide a
23448		 *      comma-space separated list from the source array. If no characters
23449		 *      are provided between the brackets, the original array source is
23450		 *      returned.
23451		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
23452		 *      execute a function of the name given. For example: `browser()` for a
23453		 *      simple function on the data source, `browser.version()` for a
23454		 *      function in a nested property or even `browser().version` to get an
23455		 *      object property if the function called returns an object. Note that
23456		 *      function notation is recommended for use in `render` rather than
23457		 *      `data` as it is much simpler to use as a renderer.
23458		 * * `null` - use the original data source for the row rather than plucking
23459		 *   data directly from it. This action has effects on two other
23460		 *   initialisation options:
23461		 *    * `defaultContent` - When null is given as the `data` option and
23462		 *      `defaultContent` is specified for the column, the value defined by
23463		 *      `defaultContent` will be used for the cell.
23464		 *    * `render` - When null is used for the `data` option and the `render`
23465		 *      option is specified for the column, the whole data source for the
23466		 *      row is used for the renderer.
23467		 * * `function` - the function given will be executed whenever DataTables
23468		 *   needs to set or get the data for a cell in the column. The function
23469		 *   takes three parameters:
23470		 *    * Parameters:
23471		 *      * `{array|object}` The data source for the row
23472		 *      * `{string}` The type call data requested - this will be 'set' when
23473		 *        setting data or 'filter', 'display', 'type', 'sort' or undefined
23474		 *        when gathering data. Note that when `undefined` is given for the
23475		 *        type DataTables expects to get the raw data for the object back<
23476		 *      * `{*}` Data to set when the second parameter is 'set'.
23477		 *    * Return:
23478		 *      * The return value from the function is not required when 'set' is
23479		 *        the type of call, but otherwise the return is what will be used
23480		 *        for the data requested.
23481		 *
23482		 * Note that `data` is a getter and setter option. If you just require
23483		 * formatting of data for output, you will likely want to use `render` which
23484		 * is simply a getter and thus simpler to use.
23485		 *
23486		 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
23487		 * name change reflects the flexibility of this property and is consistent
23488		 * with the naming of mRender. If 'mDataProp' is given, then it will still
23489		 * be used by DataTables, as it automatically maps the old name to the new
23490		 * if required.
23491		 *
23492		 *  @type string|int|function|null
23493		 *  @default null <i>Use automatically calculated column index</i>
23494		 *
23495		 *  @name DataTable.defaults.column.data
23496		 *  @dtopt Columns
23497		 *
23498		 *  @example
23499		 *    // Read table data from objects
23500		 *    // JSON structure for each row:
23501		 *    //   {
23502		 *    //      "engine": {value},
23503		 *    //      "browser": {value},
23504		 *    //      "platform": {value},
23505		 *    //      "version": {value},
23506		 *    //      "grade": {value}
23507		 *    //   }
23508		 *    $(document).ready( function() {
23509		 *      $('#example').dataTable( {
23510		 *        "ajaxSource": "sources/objects.txt",
23511		 *        "columns": [
23512		 *          { "data": "engine" },
23513		 *          { "data": "browser" },
23514		 *          { "data": "platform" },
23515		 *          { "data": "version" },
23516		 *          { "data": "grade" }
23517		 *        ]
23518		 *      } );
23519		 *    } );
23520		 *
23521		 *  @example
23522		 *    // Read information from deeply nested objects
23523		 *    // JSON structure for each row:
23524		 *    //   {
23525		 *    //      "engine": {value},
23526		 *    //      "browser": {value},
23527		 *    //      "platform": {
23528		 *    //         "inner": {value}
23529		 *    //      },
23530		 *    //      "details": [
23531		 *    //         {value}, {value}
23532		 *    //      ]
23533		 *    //   }
23534		 *    $(document).ready( function() {
23535		 *      $('#example').dataTable( {
23536		 *        "ajaxSource": "sources/deep.txt",
23537		 *        "columns": [
23538		 *          { "data": "engine" },
23539		 *          { "data": "browser" },
23540		 *          { "data": "platform.inner" },
23541		 *          { "data": "details.0" },
23542		 *          { "data": "details.1" }
23543		 *        ]
23544		 *      } );
23545		 *    } );
23546		 *
23547		 *  @example
23548		 *    // Using `data` as a function to provide different information for
23549		 *    // sorting, filtering and display. In this case, currency (price)
23550		 *    $(document).ready( function() {
23551		 *      $('#example').dataTable( {
23552		 *        "columnDefs": [ {
23553		 *          "targets": [ 0 ],
23554		 *          "data": function ( source, type, val ) {
23555		 *            if (type === 'set') {
23556		 *              source.price = val;
23557		 *              // Store the computed display and filter values for efficiency
23558		 *              source.price_display = val=="" ? "" : "$"+numberFormat(val);
23559		 *              source.price_filter  = val=="" ? "" : "$"+numberFormat(val)+" "+val;
23560		 *              return;
23561		 *            }
23562		 *            else if (type === 'display') {
23563		 *              return source.price_display;
23564		 *            }
23565		 *            else if (type === 'filter') {
23566		 *              return source.price_filter;
23567		 *            }
23568		 *            // 'sort', 'type' and undefined all just use the integer
23569		 *            return source.price;
23570		 *          }
23571		 *        } ]
23572		 *      } );
23573		 *    } );
23574		 *
23575		 *  @example
23576		 *    // Using default content
23577		 *    $(document).ready( function() {
23578		 *      $('#example').dataTable( {
23579		 *        "columnDefs": [ {
23580		 *          "targets": [ 0 ],
23581		 *          "data": null,
23582		 *          "defaultContent": "Click to edit"
23583		 *        } ]
23584		 *      } );
23585		 *    } );
23586		 *
23587		 *  @example
23588		 *    // Using array notation - outputting a list from an array
23589		 *    $(document).ready( function() {
23590		 *      $('#example').dataTable( {
23591		 *        "columnDefs": [ {
23592		 *          "targets": [ 0 ],
23593		 *          "data": "name[, ]"
23594		 *        } ]
23595		 *      } );
23596		 *    } );
23597		 *
23598		 */
23599		"mData": null,
23600	
23601	
23602		/**
23603		 * This property is the rendering partner to `data` and it is suggested that
23604		 * when you want to manipulate data for display (including filtering,
23605		 * sorting etc) without altering the underlying data for the table, use this
23606		 * property. `render` can be considered to be the the read only companion to
23607		 * `data` which is read / write (then as such more complex). Like `data`
23608		 * this option can be given in a number of different ways to effect its
23609		 * behaviour:
23610		 *
23611		 * * `integer` - treated as an array index for the data source. This is the
23612		 *   default that DataTables uses (incrementally increased for each column).
23613		 * * `string` - read an object property from the data source. There are
23614		 *   three 'special' options that can be used in the string to alter how
23615		 *   DataTables reads the data from the source object:
23616		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
23617		 *      Javascript to read from nested objects, so to can the options
23618		 *      specified in `data`. For example: `browser.version` or
23619		 *      `browser.name`. If your object parameter name contains a period, use
23620		 *      `\\` to escape it - i.e. `first\\.name`.
23621		 *    * `[]` - Array notation. DataTables can automatically combine data
23622		 *      from and array source, joining the data with the characters provided
23623		 *      between the two brackets. For example: `name[, ]` would provide a
23624		 *      comma-space separated list from the source array. If no characters
23625		 *      are provided between the brackets, the original array source is
23626		 *      returned.
23627		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
23628		 *      execute a function of the name given. For example: `browser()` for a
23629		 *      simple function on the data source, `browser.version()` for a
23630		 *      function in a nested property or even `browser().version` to get an
23631		 *      object property if the function called returns an object.
23632		 * * `object` - use different data for the different data types requested by
23633		 *   DataTables ('filter', 'display', 'type' or 'sort'). The property names
23634		 *   of the object is the data type the property refers to and the value can
23635		 *   defined using an integer, string or function using the same rules as
23636		 *   `render` normally does. Note that an `_` option _must_ be specified.
23637		 *   This is the default value to use if you haven't specified a value for
23638		 *   the data type requested by DataTables.
23639		 * * `function` - the function given will be executed whenever DataTables
23640		 *   needs to set or get the data for a cell in the column. The function
23641		 *   takes three parameters:
23642		 *    * Parameters:
23643		 *      * {array|object} The data source for the row (based on `data`)
23644		 *      * {string} The type call data requested - this will be 'filter',
23645		 *        'display', 'type' or 'sort'.
23646		 *      * {array|object} The full data source for the row (not based on
23647		 *        `data`)
23648		 *    * Return:
23649		 *      * The return value from the function is what will be used for the
23650		 *        data requested.
23651		 *
23652		 *  @type string|int|function|object|null
23653		 *  @default null Use the data source value.
23654		 *
23655		 *  @name DataTable.defaults.column.render
23656		 *  @dtopt Columns
23657		 *
23658		 *  @example
23659		 *    // Create a comma separated list from an array of objects
23660		 *    $(document).ready( function() {
23661		 *      $('#example').dataTable( {
23662		 *        "ajaxSource": "sources/deep.txt",
23663		 *        "columns": [
23664		 *          { "data": "engine" },
23665		 *          { "data": "browser" },
23666		 *          {
23667		 *            "data": "platform",
23668		 *            "render": "[, ].name"
23669		 *          }
23670		 *        ]
23671		 *      } );
23672		 *    } );
23673		 *
23674		 *  @example
23675		 *    // Execute a function to obtain data
23676		 *    $(document).ready( function() {
23677		 *      $('#example').dataTable( {
23678		 *        "columnDefs": [ {
23679		 *          "targets": [ 0 ],
23680		 *          "data": null, // Use the full data source object for the renderer's source
23681		 *          "render": "browserName()"
23682		 *        } ]
23683		 *      } );
23684		 *    } );
23685		 *
23686		 *  @example
23687		 *    // As an object, extracting different data for the different types
23688		 *    // This would be used with a data source such as:
23689		 *    //   { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
23690		 *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
23691		 *    // (which has both forms) is used for filtering for if a user inputs either format, while
23692		 *    // the formatted phone number is the one that is shown in the table.
23693		 *    $(document).ready( function() {
23694		 *      $('#example').dataTable( {
23695		 *        "columnDefs": [ {
23696		 *          "targets": [ 0 ],
23697		 *          "data": null, // Use the full data source object for the renderer's source
23698		 *          "render": {
23699		 *            "_": "phone",
23700		 *            "filter": "phone_filter",
23701		 *            "display": "phone_display"
23702		 *          }
23703		 *        } ]
23704		 *      } );
23705		 *    } );
23706		 *
23707		 *  @example
23708		 *    // Use as a function to create a link from the data source
23709		 *    $(document).ready( function() {
23710		 *      $('#example').dataTable( {
23711		 *        "columnDefs": [ {
23712		 *          "targets": [ 0 ],
23713		 *          "data": "download_link",
23714		 *          "render": function ( data, type, full ) {
23715		 *            return '<a href="'+data+'">Download</a>';
23716		 *          }
23717		 *        } ]
23718		 *      } );
23719		 *    } );
23720		 */
23721		"mRender": null,
23722	
23723	
23724		/**
23725		 * Change the cell type created for the column - either TD cells or TH cells. This
23726		 * can be useful as TH cells have semantic meaning in the table body, allowing them
23727		 * to act as a header for a row (you may wish to add scope='row' to the TH elements).
23728		 *  @type string
23729		 *  @default td
23730		 *
23731		 *  @name DataTable.defaults.column.cellType
23732		 *  @dtopt Columns
23733		 *
23734		 *  @example
23735		 *    // Make the first column use TH cells
23736		 *    $(document).ready( function() {
23737		 *      $('#example').dataTable( {
23738		 *        "columnDefs": [ {
23739		 *          "targets": [ 0 ],
23740		 *          "cellType": "th"
23741		 *        } ]
23742		 *      } );
23743		 *    } );
23744		 */
23745		"sCellType": "td",
23746	
23747	
23748		/**
23749		 * Class to give to each cell in this column.
23750		 *  @type string
23751		 *  @default <i>Empty string</i>
23752		 *
23753		 *  @name DataTable.defaults.column.class
23754		 *  @dtopt Columns
23755		 *
23756		 *  @example
23757		 *    // Using `columnDefs`
23758		 *    $(document).ready( function() {
23759		 *      $('#example').dataTable( {
23760		 *        "columnDefs": [
23761		 *          { "class": "my_class", "targets": [ 0 ] }
23762		 *        ]
23763		 *      } );
23764		 *    } );
23765		 *
23766		 *  @example
23767		 *    // Using `columns`
23768		 *    $(document).ready( function() {
23769		 *      $('#example').dataTable( {
23770		 *        "columns": [
23771		 *          { "class": "my_class" },
23772		 *          null,
23773		 *          null,
23774		 *          null,
23775		 *          null
23776		 *        ]
23777		 *      } );
23778		 *    } );
23779		 */
23780		"sClass": "",
23781	
23782		/**
23783		 * When DataTables calculates the column widths to assign to each column,
23784		 * it finds the longest string in each column and then constructs a
23785		 * temporary table and reads the widths from that. The problem with this
23786		 * is that "mmm" is much wider then "iiii", but the latter is a longer
23787		 * string - thus the calculation can go wrong (doing it properly and putting
23788		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
23789		 * a "work around" we provide this option. It will append its value to the
23790		 * text that is found to be the longest string for the column - i.e. padding.
23791		 * Generally you shouldn't need this!
23792		 *  @type string
23793		 *  @default <i>Empty string<i>
23794		 *
23795		 *  @name DataTable.defaults.column.contentPadding
23796		 *  @dtopt Columns
23797		 *
23798		 *  @example
23799		 *    // Using `columns`
23800		 *    $(document).ready( function() {
23801		 *      $('#example').dataTable( {
23802		 *        "columns": [
23803		 *          null,
23804		 *          null,
23805		 *          null,
23806		 *          {
23807		 *            "contentPadding": "mmm"
23808		 *          }
23809		 *        ]
23810		 *      } );
23811		 *    } );
23812		 */
23813		"sContentPadding": "",
23814	
23815	
23816		/**
23817		 * Allows a default value to be given for a column's data, and will be used
23818		 * whenever a null data source is encountered (this can be because `data`
23819		 * is set to null, or because the data source itself is null).
23820		 *  @type string
23821		 *  @default null
23822		 *
23823		 *  @name DataTable.defaults.column.defaultContent
23824		 *  @dtopt Columns
23825		 *
23826		 *  @example
23827		 *    // Using `columnDefs`
23828		 *    $(document).ready( function() {
23829		 *      $('#example').dataTable( {
23830		 *        "columnDefs": [
23831		 *          {
23832		 *            "data": null,
23833		 *            "defaultContent": "Edit",
23834		 *            "targets": [ -1 ]
23835		 *          }
23836		 *        ]
23837		 *      } );
23838		 *    } );
23839		 *
23840		 *  @example
23841		 *    // Using `columns`
23842		 *    $(document).ready( function() {
23843		 *      $('#example').dataTable( {
23844		 *        "columns": [
23845		 *          null,
23846		 *          null,
23847		 *          null,
23848		 *          {
23849		 *            "data": null,
23850		 *            "defaultContent": "Edit"
23851		 *          }
23852		 *        ]
23853		 *      } );
23854		 *    } );
23855		 */
23856		"sDefaultContent": null,
23857	
23858	
23859		/**
23860		 * This parameter is only used in DataTables' server-side processing. It can
23861		 * be exceptionally useful to know what columns are being displayed on the
23862		 * client side, and to map these to database fields. When defined, the names
23863		 * also allow DataTables to reorder information from the server if it comes
23864		 * back in an unexpected order (i.e. if you switch your columns around on the
23865		 * client-side, your server-side code does not also need updating).
23866		 *  @type string
23867		 *  @default <i>Empty string</i>
23868		 *
23869		 *  @name DataTable.defaults.column.name
23870		 *  @dtopt Columns
23871		 *
23872		 *  @example
23873		 *    // Using `columnDefs`
23874		 *    $(document).ready( function() {
23875		 *      $('#example').dataTable( {
23876		 *        "columnDefs": [
23877		 *          { "name": "engine", "targets": [ 0 ] },
23878		 *          { "name": "browser", "targets": [ 1 ] },
23879		 *          { "name": "platform", "targets": [ 2 ] },
23880		 *          { "name": "version", "targets": [ 3 ] },
23881		 *          { "name": "grade", "targets": [ 4 ] }
23882		 *        ]
23883		 *      } );
23884		 *    } );
23885		 *
23886		 *  @example
23887		 *    // Using `columns`
23888		 *    $(document).ready( function() {
23889		 *      $('#example').dataTable( {
23890		 *        "columns": [
23891		 *          { "name": "engine" },
23892		 *          { "name": "browser" },
23893		 *          { "name": "platform" },
23894		 *          { "name": "version" },
23895		 *          { "name": "grade" }
23896		 *        ]
23897		 *      } );
23898		 *    } );
23899		 */
23900		"sName": "",
23901	
23902	
23903		/**
23904		 * Defines a data source type for the ordering which can be used to read
23905		 * real-time information from the table (updating the internally cached
23906		 * version) prior to ordering. This allows ordering to occur on user
23907		 * editable elements such as form inputs.
23908		 *  @type string
23909		 *  @default std
23910		 *
23911		 *  @name DataTable.defaults.column.orderDataType
23912		 *  @dtopt Columns
23913		 *
23914		 *  @example
23915		 *    // Using `columnDefs`
23916		 *    $(document).ready( function() {
23917		 *      $('#example').dataTable( {
23918		 *        "columnDefs": [
23919		 *          { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
23920		 *          { "type": "numeric", "targets": [ 3 ] },
23921		 *          { "orderDataType": "dom-select", "targets": [ 4 ] },
23922		 *          { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
23923		 *        ]
23924		 *      } );
23925		 *    } );
23926		 *
23927		 *  @example
23928		 *    // Using `columns`
23929		 *    $(document).ready( function() {
23930		 *      $('#example').dataTable( {
23931		 *        "columns": [
23932		 *          null,
23933		 *          null,
23934		 *          { "orderDataType": "dom-text" },
23935		 *          { "orderDataType": "dom-text", "type": "numeric" },
23936		 *          { "orderDataType": "dom-select" },
23937		 *          { "orderDataType": "dom-checkbox" }
23938		 *        ]
23939		 *      } );
23940		 *    } );
23941		 */
23942		"sSortDataType": "std",
23943	
23944	
23945		/**
23946		 * The title of this column.
23947		 *  @type string
23948		 *  @default null <i>Derived from the 'TH' value for this column in the
23949		 *    original HTML table.</i>
23950		 *
23951		 *  @name DataTable.defaults.column.title
23952		 *  @dtopt Columns
23953		 *
23954		 *  @example
23955		 *    // Using `columnDefs`
23956		 *    $(document).ready( function() {
23957		 *      $('#example').dataTable( {
23958		 *        "columnDefs": [
23959		 *          { "title": "My column title", "targets": [ 0 ] }
23960		 *        ]
23961		 *      } );
23962		 *    } );
23963		 *
23964		 *  @example
23965		 *    // Using `columns`
23966		 *    $(document).ready( function() {
23967		 *      $('#example').dataTable( {
23968		 *        "columns": [
23969		 *          { "title": "My column title" },
23970		 *          null,
23971		 *          null,
23972		 *          null,
23973		 *          null
23974		 *        ]
23975		 *      } );
23976		 *    } );
23977		 */
23978		"sTitle": null,
23979	
23980	
23981		/**
23982		 * The type allows you to specify how the data for this column will be
23983		 * ordered. Four types (string, numeric, date and html (which will strip
23984		 * HTML tags before ordering)) are currently available. Note that only date
23985		 * formats understood by Javascript's Date() object will be accepted as type
23986		 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
23987		 * 'numeric', 'date' or 'html' (by default). Further types can be adding
23988		 * through plug-ins.
23989		 *  @type string
23990		 *  @default null <i>Auto-detected from raw data</i>
23991		 *
23992		 *  @name DataTable.defaults.column.type
23993		 *  @dtopt Columns
23994		 *
23995		 *  @example
23996		 *    // Using `columnDefs`
23997		 *    $(document).ready( function() {
23998		 *      $('#example').dataTable( {
23999		 *        "columnDefs": [
24000		 *          { "type": "html", "targets": [ 0 ] }
24001		 *        ]
24002		 *      } );
24003		 *    } );
24004		 *
24005		 *  @example
24006		 *    // Using `columns`
24007		 *    $(document).ready( function() {
24008		 *      $('#example').dataTable( {
24009		 *        "columns": [
24010		 *          { "type": "html" },
24011		 *          null,
24012		 *          null,
24013		 *          null,
24014		 *          null
24015		 *        ]
24016		 *      } );
24017		 *    } );
24018		 */
24019		"sType": null,
24020	
24021	
24022		/**
24023		 * Defining the width of the column, this parameter may take any CSS value
24024		 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
24025		 * been given a specific width through this interface ensuring that the table
24026		 * remains readable.
24027		 *  @type string
24028		 *  @default null <i>Automatic</i>
24029		 *
24030		 *  @name DataTable.defaults.column.width
24031		 *  @dtopt Columns
24032		 *
24033		 *  @example
24034		 *    // Using `columnDefs`
24035		 *    $(document).ready( function() {
24036		 *      $('#example').dataTable( {
24037		 *        "columnDefs": [
24038		 *          { "width": "20%", "targets": [ 0 ] }
24039		 *        ]
24040		 *      } );
24041		 *    } );
24042		 *
24043		 *  @example
24044		 *    // Using `columns`
24045		 *    $(document).ready( function() {
24046		 *      $('#example').dataTable( {
24047		 *        "columns": [
24048		 *          { "width": "20%" },
24049		 *          null,
24050		 *          null,
24051		 *          null,
24052		 *          null
24053		 *        ]
24054		 *      } );
24055		 *    } );
24056		 */
24057		"sWidth": null
24058	};
24059	
24060	_fnHungarianMap( DataTable.defaults.column );
24061	
24062	
24063	
24064	/**
24065	 * DataTables settings object - this holds all the information needed for a
24066	 * given table, including configuration, data and current application of the
24067	 * table options. DataTables does not have a single instance for each DataTable
24068	 * with the settings attached to that instance, but rather instances of the
24069	 * DataTable "class" are created on-the-fly as needed (typically by a
24070	 * $().dataTable() call) and the settings object is then applied to that
24071	 * instance.
24072	 *
24073	 * Note that this object is related to {@link DataTable.defaults} but this
24074	 * one is the internal data store for DataTables's cache of columns. It should
24075	 * NOT be manipulated outside of DataTables. Any configuration should be done
24076	 * through the initialisation options.
24077	 *  @namespace
24078	 *  @todo Really should attach the settings object to individual instances so we
24079	 *    don't need to create new instances on each $().dataTable() call (if the
24080	 *    table already exists). It would also save passing oSettings around and
24081	 *    into every single function. However, this is a very significant
24082	 *    architecture change for DataTables and will almost certainly break
24083	 *    backwards compatibility with older installations. This is something that
24084	 *    will be done in 2.0.
24085	 */
24086	DataTable.models.oSettings = {
24087		/**
24088		 * Primary features of DataTables and their enablement state.
24089		 *  @namespace
24090		 */
24091		"oFeatures": {
24092	
24093			/**
24094			 * Flag to say if DataTables should automatically try to calculate the
24095			 * optimum table and columns widths (true) or not (false).
24096			 * Note that this parameter will be set by the initialisation routine. To
24097			 * set a default use {@link DataTable.defaults}.
24098			 *  @type boolean
24099			 */
24100			"bAutoWidth": null,
24101	
24102			/**
24103			 * Delay the creation of TR and TD elements until they are actually
24104			 * needed by a driven page draw. This can give a significant speed
24105			 * increase for Ajax source and Javascript source data, but makes no
24106			 * difference at all for DOM and server-side processing tables.
24107			 * Note that this parameter will be set by the initialisation routine. To
24108			 * set a default use {@link DataTable.defaults}.
24109			 *  @type boolean
24110			 */
24111			"bDeferRender": null,
24112	
24113			/**
24114			 * Enable filtering on the table or not. Note that if this is disabled
24115			 * then there is no filtering at all on the table, including fnFilter.
24116			 * To just remove the filtering input use sDom and remove the 'f' option.
24117			 * Note that this parameter will be set by the initialisation routine. To
24118			 * set a default use {@link DataTable.defaults}.
24119			 *  @type boolean
24120			 */
24121			"bFilter": null,
24122	
24123			/**
24124			 * Table information element (the 'Showing x of y records' div) enable
24125			 * flag.
24126			 * Note that this parameter will be set by the initialisation routine. To
24127			 * set a default use {@link DataTable.defaults}.
24128			 *  @type boolean
24129			 */
24130			"bInfo": null,
24131	
24132			/**
24133			 * Present a user control allowing the end user to change the page size
24134			 * when pagination is enabled.
24135			 * Note that this parameter will be set by the initialisation routine. To
24136			 * set a default use {@link DataTable.defaults}.
24137			 *  @type boolean
24138			 */
24139			"bLengthChange": null,
24140	
24141			/**
24142			 * Pagination enabled or not. Note that if this is disabled then length
24143			 * changing must also be disabled.
24144			 * Note that this parameter will be set by the initialisation routine. To
24145			 * set a default use {@link DataTable.defaults}.
24146			 *  @type boolean
24147			 */
24148			"bPaginate": null,
24149	
24150			/**
24151			 * Processing indicator enable flag whenever DataTables is enacting a
24152			 * user request - typically an Ajax request for server-side processing.
24153			 * Note that this parameter will be set by the initialisation routine. To
24154			 * set a default use {@link DataTable.defaults}.
24155			 *  @type boolean
24156			 */
24157			"bProcessing": null,
24158	
24159			/**
24160			 * Server-side processing enabled flag - when enabled DataTables will
24161			 * get all data from the server for every draw - there is no filtering,
24162			 * sorting or paging done on the client-side.
24163			 * Note that this parameter will be set by the initialisation routine. To
24164			 * set a default use {@link DataTable.defaults}.
24165			 *  @type boolean
24166			 */
24167			"bServerSide": null,
24168	
24169			/**
24170			 * Sorting enablement flag.
24171			 * Note that this parameter will be set by the initialisation routine. To
24172			 * set a default use {@link DataTable.defaults}.
24173			 *  @type boolean
24174			 */
24175			"bSort": null,
24176	
24177			/**
24178			 * Multi-column sorting
24179			 * Note that this parameter will be set by the initialisation routine. To
24180			 * set a default use {@link DataTable.defaults}.
24181			 *  @type boolean
24182			 */
24183			"bSortMulti": null,
24184	
24185			/**
24186			 * Apply a class to the columns which are being sorted to provide a
24187			 * visual highlight or not. This can slow things down when enabled since
24188			 * there is a lot of DOM interaction.
24189			 * Note that this parameter will be set by the initialisation routine. To
24190			 * set a default use {@link DataTable.defaults}.
24191			 *  @type boolean
24192			 */
24193			"bSortClasses": null,
24194	
24195			/**
24196			 * State saving enablement flag.
24197			 * Note that this parameter will be set by the initialisation routine. To
24198			 * set a default use {@link DataTable.defaults}.
24199			 *  @type boolean
24200			 */
24201			"bStateSave": null
24202		},
24203	
24204	
24205		/**
24206		 * Scrolling settings for a table.
24207		 *  @namespace
24208		 */
24209		"oScroll": {
24210			/**
24211			 * When the table is shorter in height than sScrollY, collapse the
24212			 * table container down to the height of the table (when true).
24213			 * Note that this parameter will be set by the initialisation routine. To
24214			 * set a default use {@link DataTable.defaults}.
24215			 *  @type boolean
24216			 */
24217			"bCollapse": null,
24218	
24219			/**
24220			 * Width of the scrollbar for the web-browser's platform. Calculated
24221			 * during table initialisation.
24222			 *  @type int
24223			 *  @default 0
24224			 */
24225			"iBarWidth": 0,
24226	
24227			/**
24228			 * Viewport width for horizontal scrolling. Horizontal scrolling is
24229			 * disabled if an empty string.
24230			 * Note that this parameter will be set by the initialisation routine. To
24231			 * set a default use {@link DataTable.defaults}.
24232			 *  @type string
24233			 */
24234			"sX": null,
24235	
24236			/**
24237			 * Width to expand the table to when using x-scrolling. Typically you
24238			 * should not need to use this.
24239			 * Note that this parameter will be set by the initialisation routine. To
24240			 * set a default use {@link DataTable.defaults}.
24241			 *  @type string
24242			 *  @deprecated
24243			 */
24244			"sXInner": null,
24245	
24246			/**
24247			 * Viewport height for vertical scrolling. Vertical scrolling is disabled
24248			 * if an empty string.
24249			 * Note that this parameter will be set by the initialisation routine. To
24250			 * set a default use {@link DataTable.defaults}.
24251			 *  @type string
24252			 */
24253			"sY": null
24254		},
24255	
24256		/**
24257		 * Language information for the table.
24258		 *  @namespace
24259		 *  @extends DataTable.defaults.oLanguage
24260		 */
24261		"oLanguage": {
24262			/**
24263			 * Information callback function. See
24264			 * {@link DataTable.defaults.fnInfoCallback}
24265			 *  @type function
24266			 *  @default null
24267			 */
24268			"fnInfoCallback": null
24269		},
24270	
24271		/**
24272		 * Browser support parameters
24273		 *  @namespace
24274		 */
24275		"oBrowser": {
24276			/**
24277			 * Indicate if the browser incorrectly calculates width:100% inside a
24278			 * scrolling element (IE6/7)
24279			 *  @type boolean
24280			 *  @default false
24281			 */
24282			"bScrollOversize": false,
24283	
24284			/**
24285			 * Determine if the vertical scrollbar is on the right or left of the
24286			 * scrolling container - needed for rtl language layout, although not
24287			 * all browsers move the scrollbar (Safari).
24288			 *  @type boolean
24289			 *  @default false
24290			 */
24291			"bScrollbarLeft": false,
24292	
24293			/**
24294			 * Flag for if `getBoundingClientRect` is fully supported or not
24295			 *  @type boolean
24296			 *  @default false
24297			 */
24298			"bBounding": false,
24299	
24300			/**
24301			 * Browser scrollbar width
24302			 *  @type integer
24303			 *  @default 0
24304			 */
24305			"barWidth": 0
24306		},
24307	
24308	
24309		"ajax": null,
24310	
24311	
24312		/**
24313		 * Array referencing the nodes which are used for the features. The
24314		 * parameters of this object match what is allowed by sDom - i.e.
24315		 *   <ul>
24316		 *     <li>'l' - Length changing</li>
24317		 *     <li>'f' - Filtering input</li>
24318		 *     <li>'t' - The table!</li>
24319		 *     <li>'i' - Information</li>
24320		 *     <li>'p' - Pagination</li>
24321		 *     <li>'r' - pRocessing</li>
24322		 *   </ul>
24323		 *  @type array
24324		 *  @default []
24325		 */
24326		"aanFeatures": [],
24327	
24328		/**
24329		 * Store data information - see {@link DataTable.models.oRow} for detailed
24330		 * information.
24331		 *  @type array
24332		 *  @default []
24333		 */
24334		"aoData": [],
24335	
24336		/**
24337		 * Array of indexes which are in the current display (after filtering etc)
24338		 *  @type array
24339		 *  @default []
24340		 */
24341		"aiDisplay": [],
24342	
24343		/**
24344		 * Array of indexes for display - no filtering
24345		 *  @type array
24346		 *  @default []
24347		 */
24348		"aiDisplayMaster": [],
24349	
24350		/**
24351		 * Map of row ids to data indexes
24352		 *  @type object
24353		 *  @default {}
24354		 */
24355		"aIds": {},
24356	
24357		/**
24358		 * Store information about each column that is in use
24359		 *  @type array
24360		 *  @default []
24361		 */
24362		"aoColumns": [],
24363	
24364		/**
24365		 * Store information about the table's header
24366		 *  @type array
24367		 *  @default []
24368		 */
24369		"aoHeader": [],
24370	
24371		/**
24372		 * Store information about the table's footer
24373		 *  @type array
24374		 *  @default []
24375		 */
24376		"aoFooter": [],
24377	
24378		/**
24379		 * Store the applied global search information in case we want to force a
24380		 * research or compare the old search to a new one.
24381		 * Note that this parameter will be set by the initialisation routine. To
24382		 * set a default use {@link DataTable.defaults}.
24383		 *  @namespace
24384		 *  @extends DataTable.models.oSearch
24385		 */
24386		"oPreviousSearch": {},
24387	
24388		/**
24389		 * Store the applied search for each column - see
24390		 * {@link DataTable.models.oSearch} for the format that is used for the
24391		 * filtering information for each column.
24392		 *  @type array
24393		 *  @default []
24394		 */
24395		"aoPreSearchCols": [],
24396	
24397		/**
24398		 * Sorting that is applied to the table. Note that the inner arrays are
24399		 * used in the following manner:
24400		 * <ul>
24401		 *   <li>Index 0 - column number</li>
24402		 *   <li>Index 1 - current sorting direction</li>
24403		 * </ul>
24404		 * Note that this parameter will be set by the initialisation routine. To
24405		 * set a default use {@link DataTable.defaults}.
24406		 *  @type array
24407		 *  @todo These inner arrays should really be objects
24408		 */
24409		"aaSorting": null,
24410	
24411		/**
24412		 * Sorting that is always applied to the table (i.e. prefixed in front of
24413		 * aaSorting).
24414		 * Note that this parameter will be set by the initialisation routine. To
24415		 * set a default use {@link DataTable.defaults}.
24416		 *  @type array
24417		 *  @default []
24418		 */
24419		"aaSortingFixed": [],
24420	
24421		/**
24422		 * Classes to use for the striping of a table.
24423		 * Note that this parameter will be set by the initialisation routine. To
24424		 * set a default use {@link DataTable.defaults}.
24425		 *  @type array
24426		 *  @default []
24427		 */
24428		"asStripeClasses": null,
24429	
24430		/**
24431		 * If restoring a table - we should restore its striping classes as well
24432		 *  @type array
24433		 *  @default []
24434		 */
24435		"asDestroyStripes": [],
24436	
24437		/**
24438		 * If restoring a table - we should restore its width
24439		 *  @type int
24440		 *  @default 0
24441		 */
24442		"sDestroyWidth": 0,
24443	
24444		/**
24445		 * Callback functions array for every time a row is inserted (i.e. on a draw).
24446		 *  @type array
24447		 *  @default []
24448		 */
24449		"aoRowCallback": [],
24450	
24451		/**
24452		 * Callback functions for the header on each draw.
24453		 *  @type array
24454		 *  @default []
24455		 */
24456		"aoHeaderCallback": [],
24457	
24458		/**
24459		 * Callback function for the footer on each draw.
24460		 *  @type array
24461		 *  @default []
24462		 */
24463		"aoFooterCallback": [],
24464	
24465		/**
24466		 * Array of callback functions for draw callback functions
24467		 *  @type array
24468		 *  @default []
24469		 */
24470		"aoDrawCallback": [],
24471	
24472		/**
24473		 * Array of callback functions for row created function
24474		 *  @type array
24475		 *  @default []
24476		 */
24477		"aoRowCreatedCallback": [],
24478	
24479		/**
24480		 * Callback functions for just before the table is redrawn. A return of
24481		 * false will be used to cancel the draw.
24482		 *  @type array
24483		 *  @default []
24484		 */
24485		"aoPreDrawCallback": [],
24486	
24487		/**
24488		 * Callback functions for when the table has been initialised.
24489		 *  @type array
24490		 *  @default []
24491		 */
24492		"aoInitComplete": [],
24493	
24494	
24495		/**
24496		 * Callbacks for modifying the settings to be stored for state saving, prior to
24497		 * saving state.
24498		 *  @type array
24499		 *  @default []
24500		 */
24501		"aoStateSaveParams": [],
24502	
24503		/**
24504		 * Callbacks for modifying the settings that have been stored for state saving
24505		 * prior to using the stored values to restore the state.
24506		 *  @type array
24507		 *  @default []
24508		 */
24509		"aoStateLoadParams": [],
24510	
24511		/**
24512		 * Callbacks for operating on the settings object once the saved state has been
24513		 * loaded
24514		 *  @type array
24515		 *  @default []
24516		 */
24517		"aoStateLoaded": [],
24518	
24519		/**
24520		 * Cache the table ID for quick access
24521		 *  @type string
24522		 *  @default <i>Empty string</i>
24523		 */
24524		"sTableId": "",
24525	
24526		/**
24527		 * The TABLE node for the main table
24528		 *  @type node
24529		 *  @default null
24530		 */
24531		"nTable": null,
24532	
24533		/**
24534		 * Permanent ref to the thead element
24535		 *  @type node
24536		 *  @default null
24537		 */
24538		"nTHead": null,
24539	
24540		/**
24541		 * Permanent ref to the tfoot element - if it exists
24542		 *  @type node
24543		 *  @default null
24544		 */
24545		"nTFoot": null,
24546	
24547		/**
24548		 * Permanent ref to the tbody element
24549		 *  @type node
24550		 *  @default null
24551		 */
24552		"nTBody": null,
24553	
24554		/**
24555		 * Cache the wrapper node (contains all DataTables controlled elements)
24556		 *  @type node
24557		 *  @default null
24558		 */
24559		"nTableWrapper": null,
24560	
24561		/**
24562		 * Indicate if when using server-side processing the loading of data
24563		 * should be deferred until the second draw.
24564		 * Note that this parameter will be set by the initialisation routine. To
24565		 * set a default use {@link DataTable.defaults}.
24566		 *  @type boolean
24567		 *  @default false
24568		 */
24569		"bDeferLoading": false,
24570	
24571		/**
24572		 * Indicate if all required information has been read in
24573		 *  @type boolean
24574		 *  @default false
24575		 */
24576		"bInitialised": false,
24577	
24578		/**
24579		 * Information about open rows. Each object in the array has the parameters
24580		 * 'nTr' and 'nParent'
24581		 *  @type array
24582		 *  @default []
24583		 */
24584		"aoOpenRows": [],
24585	
24586		/**
24587		 * Dictate the positioning of DataTables' control elements - see
24588		 * {@link DataTable.model.oInit.sDom}.
24589		 * Note that this parameter will be set by the initialisation routine. To
24590		 * set a default use {@link DataTable.defaults}.
24591		 *  @type string
24592		 *  @default null
24593		 */
24594		"sDom": null,
24595	
24596		/**
24597		 * Search delay (in mS)
24598		 *  @type integer
24599		 *  @default null
24600		 */
24601		"searchDelay": null,
24602	
24603		/**
24604		 * Which type of pagination should be used.
24605		 * Note that this parameter will be set by the initialisation routine. To
24606		 * set a default use {@link DataTable.defaults}.
24607		 *  @type string
24608		 *  @default two_button
24609		 */
24610		"sPaginationType": "two_button",
24611	
24612		/**
24613		 * The state duration (for `stateSave`) in seconds.
24614		 * Note that this parameter will be set by the initialisation routine. To
24615		 * set a default use {@link DataTable.defaults}.
24616		 *  @type int
24617		 *  @default 0
24618		 */
24619		"iStateDuration": 0,
24620	
24621		/**
24622		 * Array of callback functions for state saving. Each array element is an
24623		 * object with the following parameters:
24624		 *   <ul>
24625		 *     <li>function:fn - function to call. Takes two parameters, oSettings
24626		 *       and the JSON string to save that has been thus far created. Returns
24627		 *       a JSON string to be inserted into a json object
24628		 *       (i.e. '"param": [ 0, 1, 2]')</li>
24629		 *     <li>string:sName - name of callback</li>
24630		 *   </ul>
24631		 *  @type array
24632		 *  @default []
24633		 */
24634		"aoStateSave": [],
24635	
24636		/**
24637		 * Array of callback functions for state loading. Each array element is an
24638		 * object with the following parameters:
24639		 *   <ul>
24640		 *     <li>function:fn - function to call. Takes two parameters, oSettings
24641		 *       and the object stored. May return false to cancel state loading</li>
24642		 *     <li>string:sName - name of callback</li>
24643		 *   </ul>
24644		 *  @type array
24645		 *  @default []
24646		 */
24647		"aoStateLoad": [],
24648	
24649		/**
24650		 * State that was saved. Useful for back reference
24651		 *  @type object
24652		 *  @default null
24653		 */
24654		"oSavedState": null,
24655	
24656		/**
24657		 * State that was loaded. Useful for back reference
24658		 *  @type object
24659		 *  @default null
24660		 */
24661		"oLoadedState": null,
24662	
24663		/**
24664		 * Source url for AJAX data for the table.
24665		 * Note that this parameter will be set by the initialisation routine. To
24666		 * set a default use {@link DataTable.defaults}.
24667		 *  @type string
24668		 *  @default null
24669		 */
24670		"sAjaxSource": null,
24671	
24672		/**
24673		 * Property from a given object from which to read the table data from. This
24674		 * can be an empty string (when not server-side processing), in which case
24675		 * it is  assumed an an array is given directly.
24676		 * Note that this parameter will be set by the initialisation routine. To
24677		 * set a default use {@link DataTable.defaults}.
24678		 *  @type string
24679		 */
24680		"sAjaxDataProp": null,
24681	
24682		/**
24683		 * The last jQuery XHR object that was used for server-side data gathering.
24684		 * This can be used for working with the XHR information in one of the
24685		 * callbacks
24686		 *  @type object
24687		 *  @default null
24688		 */
24689		"jqXHR": null,
24690	
24691		/**
24692		 * JSON returned from the server in the last Ajax request
24693		 *  @type object
24694		 *  @default undefined
24695		 */
24696		"json": undefined,
24697	
24698		/**
24699		 * Data submitted as part of the last Ajax request
24700		 *  @type object
24701		 *  @default undefined
24702		 */
24703		"oAjaxData": undefined,
24704	
24705		/**
24706		 * Function to get the server-side data.
24707		 * Note that this parameter will be set by the initialisation routine. To
24708		 * set a default use {@link DataTable.defaults}.
24709		 *  @type function
24710		 */
24711		"fnServerData": null,
24712	
24713		/**
24714		 * Functions which are called prior to sending an Ajax request so extra
24715		 * parameters can easily be sent to the server
24716		 *  @type array
24717		 *  @default []
24718		 */
24719		"aoServerParams": [],
24720	
24721		/**
24722		 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
24723		 * required).
24724		 * Note that this parameter will be set by the initialisation routine. To
24725		 * set a default use {@link DataTable.defaults}.
24726		 *  @type string
24727		 */
24728		"sServerMethod": null,
24729	
24730		/**
24731		 * Format numbers for display.
24732		 * Note that this parameter will be set by the initialisation routine. To
24733		 * set a default use {@link DataTable.defaults}.
24734		 *  @type function
24735		 */
24736		"fnFormatNumber": null,
24737	
24738		/**
24739		 * List of options that can be used for the user selectable length menu.
24740		 * Note that this parameter will be set by the initialisation routine. To
24741		 * set a default use {@link DataTable.defaults}.
24742		 *  @type array
24743		 *  @default []
24744		 */
24745		"aLengthMenu": null,
24746	
24747		/**
24748		 * Counter for the draws that the table does. Also used as a tracker for
24749		 * server-side processing
24750		 *  @type int
24751		 *  @default 0
24752		 */
24753		"iDraw": 0,
24754	
24755		/**
24756		 * Indicate if a redraw is being done - useful for Ajax
24757		 *  @type boolean
24758		 *  @default false
24759		 */
24760		"bDrawing": false,
24761	
24762		/**
24763		 * Draw index (iDraw) of the last error when parsing the returned data
24764		 *  @type int
24765		 *  @default -1
24766		 */
24767		"iDrawError": -1,
24768	
24769		/**
24770		 * Paging display length
24771		 *  @type int
24772		 *  @default 10
24773		 */
24774		"_iDisplayLength": 10,
24775	
24776		/**
24777		 * Paging start point - aiDisplay index
24778		 *  @type int
24779		 *  @default 0
24780		 */
24781		"_iDisplayStart": 0,
24782	
24783		/**
24784		 * Server-side processing - number of records in the result set
24785		 * (i.e. before filtering), Use fnRecordsTotal rather than
24786		 * this property to get the value of the number of records, regardless of
24787		 * the server-side processing setting.
24788		 *  @type int
24789		 *  @default 0
24790		 *  @private
24791		 */
24792		"_iRecordsTotal": 0,
24793	
24794		/**
24795		 * Server-side processing - number of records in the current display set
24796		 * (i.e. after filtering). Use fnRecordsDisplay rather than
24797		 * this property to get the value of the number of records, regardless of
24798		 * the server-side processing setting.
24799		 *  @type boolean
24800		 *  @default 0
24801		 *  @private
24802		 */
24803		"_iRecordsDisplay": 0,
24804	
24805		/**
24806		 * The classes to use for the table
24807		 *  @type object
24808		 *  @default {}
24809		 */
24810		"oClasses": {},
24811	
24812		/**
24813		 * Flag attached to the settings object so you can check in the draw
24814		 * callback if filtering has been done in the draw. Deprecated in favour of
24815		 * events.
24816		 *  @type boolean
24817		 *  @default false
24818		 *  @deprecated
24819		 */
24820		"bFiltered": false,
24821	
24822		/**
24823		 * Flag attached to the settings object so you can check in the draw
24824		 * callback if sorting has been done in the draw. Deprecated in favour of
24825		 * events.
24826		 *  @type boolean
24827		 *  @default false
24828		 *  @deprecated
24829		 */
24830		"bSorted": false,
24831	
24832		/**
24833		 * Indicate that if multiple rows are in the header and there is more than
24834		 * one unique cell per column, if the top one (true) or bottom one (false)
24835		 * should be used for sorting / title by DataTables.
24836		 * Note that this parameter will be set by the initialisation routine. To
24837		 * set a default use {@link DataTable.defaults}.
24838		 *  @type boolean
24839		 */
24840		"bSortCellsTop": null,
24841	
24842		/**
24843		 * Initialisation object that is used for the table
24844		 *  @type object
24845		 *  @default null
24846		 */
24847		"oInit": null,
24848	
24849		/**
24850		 * Destroy callback functions - for plug-ins to attach themselves to the
24851		 * destroy so they can clean up markup and events.
24852		 *  @type array
24853		 *  @default []
24854		 */
24855		"aoDestroyCallback": [],
24856	
24857	
24858		/**
24859		 * Get the number of records in the current record set, before filtering
24860		 *  @type function
24861		 */
24862		"fnRecordsTotal": function ()
24863		{
24864			return _fnDataSource( this ) == 'ssp' ?
24865				this._iRecordsTotal * 1 :
24866				this.aiDisplayMaster.length;
24867		},
24868	
24869		/**
24870		 * Get the number of records in the current record set, after filtering
24871		 *  @type function
24872		 */
24873		"fnRecordsDisplay": function ()
24874		{
24875			return _fnDataSource( this ) == 'ssp' ?
24876				this._iRecordsDisplay * 1 :
24877				this.aiDisplay.length;
24878		},
24879	
24880		/**
24881		 * Get the display end point - aiDisplay index
24882		 *  @type function
24883		 */
24884		"fnDisplayEnd": function ()
24885		{
24886			var
24887				len      = this._iDisplayLength,
24888				start    = this._iDisplayStart,
24889				calc     = start + len,
24890				records  = this.aiDisplay.length,
24891				features = this.oFeatures,
24892				paginate = features.bPaginate;
24893	
24894			if ( features.bServerSide ) {
24895				return paginate === false || len === -1 ?
24896					start + records :
24897					Math.min( start+len, this._iRecordsDisplay );
24898			}
24899			else {
24900				return ! paginate || calc>records || len===-1 ?
24901					records :
24902					calc;
24903			}
24904		},
24905	
24906		/**
24907		 * The DataTables object for this table
24908		 *  @type object
24909		 *  @default null
24910		 */
24911		"oInstance": null,
24912	
24913		/**
24914		 * Unique identifier for each instance of the DataTables object. If there
24915		 * is an ID on the table node, then it takes that value, otherwise an
24916		 * incrementing internal counter is used.
24917		 *  @type string
24918		 *  @default null
24919		 */
24920		"sInstance": null,
24921	
24922		/**
24923		 * tabindex attribute value that is added to DataTables control elements, allowing
24924		 * keyboard navigation of the table and its controls.
24925		 */
24926		"iTabIndex": 0,
24927	
24928		/**
24929		 * DIV container for the footer scrolling table if scrolling
24930		 */
24931		"nScrollHead": null,
24932	
24933		/**
24934		 * DIV container for the footer scrolling table if scrolling
24935		 */
24936		"nScrollFoot": null,
24937	
24938		/**
24939		 * Last applied sort
24940		 *  @type array
24941		 *  @default []
24942		 */
24943		"aLastSort": [],
24944	
24945		/**
24946		 * Stored plug-in instances
24947		 *  @type object
24948		 *  @default {}
24949		 */
24950		"oPlugins": {},
24951	
24952		/**
24953		 * Function used to get a row's id from the row's data
24954		 *  @type function
24955		 *  @default null
24956		 */
24957		"rowIdFn": null,
24958	
24959		/**
24960		 * Data location where to store a row's id
24961		 *  @type string
24962		 *  @default null
24963		 */
24964		"rowId": null
24965	};
24966
24967	/**
24968	 * Extension object for DataTables that is used to provide all extension
24969	 * options.
24970	 *
24971	 * Note that the `DataTable.ext` object is available through
24972	 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
24973	 * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
24974	 *  @namespace
24975	 *  @extends DataTable.models.ext
24976	 */
24977	
24978	
24979	/**
24980	 * DataTables extensions
24981	 * 
24982	 * This namespace acts as a collection area for plug-ins that can be used to
24983	 * extend DataTables capabilities. Indeed many of the build in methods
24984	 * use this method to provide their own capabilities (sorting methods for
24985	 * example).
24986	 *
24987	 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
24988	 * reasons
24989	 *
24990	 *  @namespace
24991	 */
24992	DataTable.ext = _ext = {
24993		/**
24994		 * Buttons. For use with the Buttons extension for DataTables. This is
24995		 * defined here so other extensions can define buttons regardless of load
24996		 * order. It is _not_ used by DataTables core.
24997		 *
24998		 *  @type object
24999		 *  @default {}
25000		 */
25001		buttons: {},
25002	
25003	
25004		/**
25005		 * Element class names
25006		 *
25007		 *  @type object
25008		 *  @default {}
25009		 */
25010		classes: {},
25011	
25012	
25013		/**
25014		 * DataTables build type (expanded by the download builder)
25015		 *
25016		 *  @type string
25017		 */
25018		builder: "-source-",
25019	
25020	
25021		/**
25022		 * Error reporting.
25023		 * 
25024		 * How should DataTables report an error. Can take the value 'alert',
25025		 * 'throw', 'none' or a function.
25026		 *
25027		 *  @type string|function
25028		 *  @default alert
25029		 */
25030		errMode: "alert",
25031	
25032	
25033		/**
25034		 * Feature plug-ins.
25035		 * 
25036		 * This is an array of objects which describe the feature plug-ins that are
25037		 * available to DataTables. These feature plug-ins are then available for
25038		 * use through the `dom` initialisation option.
25039		 * 
25040		 * Each feature plug-in is described by an object which must have the
25041		 * following properties:
25042		 * 
25043		 * * `fnInit` - function that is used to initialise the plug-in,
25044		 * * `cFeature` - a character so the feature can be enabled by the `dom`
25045		 *   instillation option. This is case sensitive.
25046		 *
25047		 * The `fnInit` function has the following input parameters:
25048		 *
25049		 * 1. `{object}` DataTables settings object: see
25050		 *    {@link DataTable.models.oSettings}
25051		 *
25052		 * And the following return is expected:
25053		 * 
25054		 * * {node|null} The element which contains your feature. Note that the
25055		 *   return may also be void if your plug-in does not require to inject any
25056		 *   DOM elements into DataTables control (`dom`) - for example this might
25057		 *   be useful when developing a plug-in which allows table control via
25058		 *   keyboard entry
25059		 *
25060		 *  @type array
25061		 *
25062		 *  @example
25063		 *    $.fn.dataTable.ext.features.push( {
25064		 *      "fnInit": function( oSettings ) {
25065		 *        return new TableTools( { "oDTSettings": oSettings } );
25066		 *      },
25067		 *      "cFeature": "T"
25068		 *    } );
25069		 */
25070		feature: [],
25071	
25072	
25073		/**
25074		 * Row searching.
25075		 * 
25076		 * This method of searching is complimentary to the default type based
25077		 * searching, and a lot more comprehensive as it allows you complete control
25078		 * over the searching logic. Each element in this array is a function
25079		 * (parameters described below) that is called for every row in the table,
25080		 * and your logic decides if it should be included in the searching data set
25081		 * or not.
25082		 *
25083		 * Searching functions have the following input parameters:
25084		 *
25085		 * 1. `{object}` DataTables settings object: see
25086		 *    {@link DataTable.models.oSettings}
25087		 * 2. `{array|object}` Data for the row to be processed (same as the
25088		 *    original format that was passed in as the data source, or an array
25089		 *    from a DOM data source
25090		 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
25091		 *    can be useful to retrieve the `TR` element if you need DOM interaction.
25092		 *
25093		 * And the following return is expected:
25094		 *
25095		 * * {boolean} Include the row in the searched result set (true) or not
25096		 *   (false)
25097		 *
25098		 * Note that as with the main search ability in DataTables, technically this
25099		 * is "filtering", since it is subtractive. However, for consistency in
25100		 * naming we call it searching here.
25101		 *
25102		 *  @type array
25103		 *  @default []
25104		 *
25105		 *  @example
25106		 *    // The following example shows custom search being applied to the
25107		 *    // fourth column (i.e. the data[3] index) based on two input values
25108		 *    // from the end-user, matching the data in a certain range.
25109		 *    $.fn.dataTable.ext.search.push(
25110		 *      function( settings, data, dataIndex ) {
25111		 *        var min = document.getElementById('min').value * 1;
25112		 *        var max = document.getElementById('max').value * 1;
25113		 *        var version = data[3] == "-" ? 0 : data[3]*1;
25114		 *
25115		 *        if ( min == "" && max == "" ) {
25116		 *          return true;
25117		 *        }
25118		 *        else if ( min == "" && version < max ) {
25119		 *          return true;
25120		 *        }
25121		 *        else if ( min < version && "" == max ) {
25122		 *          return true;
25123		 *        }
25124		 *        else if ( min < version && version < max ) {
25125		 *          return true;
25126		 *        }
25127		 *        return false;
25128		 *      }
25129		 *    );
25130		 */
25131		search: [],
25132	
25133	
25134		/**
25135		 * Selector extensions
25136		 *
25137		 * The `selector` option can be used to extend the options available for the
25138		 * selector modifier options (`selector-modifier` object data type) that
25139		 * each of the three built in selector types offer (row, column and cell +
25140		 * their plural counterparts). For example the Select extension uses this
25141		 * mechanism to provide an option to select only rows, columns and cells
25142		 * that have been marked as selected by the end user (`{selected: true}`),
25143		 * which can be used in conjunction with the existing built in selector
25144		 * options.
25145		 *
25146		 * Each property is an array to which functions can be pushed. The functions
25147		 * take three attributes:
25148		 *
25149		 * * Settings object for the host table
25150		 * * Options object (`selector-modifier` object type)
25151		 * * Array of selected item indexes
25152		 *
25153		 * The return is an array of the resulting item indexes after the custom
25154		 * selector has been applied.
25155		 *
25156		 *  @type object
25157		 */
25158		selector: {
25159			cell: [],
25160			column: [],
25161			row: []
25162		},
25163	
25164	
25165		/**
25166		 * Internal functions, exposed for used in plug-ins.
25167		 * 
25168		 * Please note that you should not need to use the internal methods for
25169		 * anything other than a plug-in (and even then, try to avoid if possible).
25170		 * The internal function may change between releases.
25171		 *
25172		 *  @type object
25173		 *  @default {}
25174		 */
25175		internal: {},
25176	
25177	
25178		/**
25179		 * Legacy configuration options. Enable and disable legacy options that
25180		 * are available in DataTables.
25181		 *
25182		 *  @type object
25183		 */
25184		legacy: {
25185			/**
25186			 * Enable / disable DataTables 1.9 compatible server-side processing
25187			 * requests
25188			 *
25189			 *  @type boolean
25190			 *  @default null
25191			 */
25192			ajax: null
25193		},
25194	
25195	
25196		/**
25197		 * Pagination plug-in methods.
25198		 * 
25199		 * Each entry in this object is a function and defines which buttons should
25200		 * be shown by the pagination rendering method that is used for the table:
25201		 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
25202		 * buttons are displayed in the document, while the functions here tell it
25203		 * what buttons to display. This is done by returning an array of button
25204		 * descriptions (what each button will do).
25205		 *
25206		 * Pagination types (the four built in options and any additional plug-in
25207		 * options defined here) can be used through the `paginationType`
25208		 * initialisation parameter.
25209		 *
25210		 * The functions defined take two parameters:
25211		 *
25212		 * 1. `{int} page` The current page index
25213		 * 2. `{int} pages` The number of pages in the table
25214		 *
25215		 * Each function is expected to return an array where each element of the
25216		 * array can be one of:
25217		 *
25218		 * * `first` - Jump to first page when activated
25219		 * * `last` - Jump to last page when activated
25220		 * * `previous` - Show previous page when activated
25221		 * * `next` - Show next page when activated
25222		 * * `{int}` - Show page of the index given
25223		 * * `{array}` - A nested array containing the above elements to add a
25224		 *   containing 'DIV' element (might be useful for styling).
25225		 *
25226		 * Note that DataTables v1.9- used this object slightly differently whereby
25227		 * an object with two functions would be defined for each plug-in. That
25228		 * ability is still supported by DataTables 1.10+ to provide backwards
25229		 * compatibility, but this option of use is now decremented and no longer
25230		 * documented in DataTables 1.10+.
25231		 *
25232		 *  @type object
25233		 *  @default {}
25234		 *
25235		 *  @example
25236		 *    // Show previous, next and current page buttons only
25237		 *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
25238		 *      return [ 'previous', page, 'next' ];
25239		 *    };
25240		 */
25241		pager: {},
25242	
25243	
25244		renderer: {
25245			pageButton: {},
25246			header: {}
25247		},
25248	
25249	
25250		/**
25251		 * Ordering plug-ins - custom data source
25252		 * 
25253		 * The extension options for ordering of data available here is complimentary
25254		 * to the default type based ordering that DataTables typically uses. It
25255		 * allows much greater control over the the data that is being used to
25256		 * order a column, but is necessarily therefore more complex.
25257		 * 
25258		 * This type of ordering is useful if you want to do ordering based on data
25259		 * live from the DOM (for example the contents of an 'input' element) rather
25260		 * than just the static string that DataTables knows of.
25261		 * 
25262		 * The way these plug-ins work is that you create an array of the values you
25263		 * wish to be ordering for the column in question and then return that
25264		 * array. The data in the array much be in the index order of the rows in
25265		 * the table (not the currently ordering order!). Which order data gathering
25266		 * function is run here depends on the `dt-init columns.orderDataType`
25267		 * parameter that is used for the column (if any).
25268		 *
25269		 * The functions defined take two parameters:
25270		 *
25271		 * 1. `{object}` DataTables settings object: see
25272		 *    {@link DataTable.models.oSettings}
25273		 * 2. `{int}` Target column index
25274		 *
25275		 * Each function is expected to return an array:
25276		 *
25277		 * * `{array}` Data for the column to be ordering upon
25278		 *
25279		 *  @type array
25280		 *
25281		 *  @example
25282		 *    // Ordering using `input` node values
25283		 *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
25284		 *    {
25285		 *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
25286		 *        return $('input', td).val();
25287		 *      } );
25288		 *    }
25289		 */
25290		order: {},
25291	
25292	
25293		/**
25294		 * Type based plug-ins.
25295		 *
25296		 * Each column in DataTables has a type assigned to it, either by automatic
25297		 * detection or by direct assignment using the `type` option for the column.
25298		 * The type of a column will effect how it is ordering and search (plug-ins
25299		 * can also make use of the column type if required).
25300		 *
25301		 * @namespace
25302		 */
25303		type: {
25304			/**
25305			 * Type detection functions.
25306			 *
25307			 * The functions defined in this object are used to automatically detect
25308			 * a column's type, making initialisation of DataTables super easy, even
25309			 * when complex data is in the table.
25310			 *
25311			 * The functions defined take two parameters:
25312			 *
25313		     *  1. `{*}` Data from the column cell to be analysed
25314		     *  2. `{settings}` DataTables settings object. This can be used to
25315		     *     perform context specific type detection - for example detection
25316		     *     based on language settings such as using a comma for a decimal
25317		     *     place. Generally speaking the options from the settings will not
25318		     *     be required
25319			 *
25320			 * Each function is expected to return:
25321			 *
25322			 * * `{string|null}` Data type detected, or null if unknown (and thus
25323			 *   pass it on to the other type detection functions.
25324			 *
25325			 *  @type array
25326			 *
25327			 *  @example
25328			 *    // Currency type detection plug-in:
25329			 *    $.fn.dataTable.ext.type.detect.push(
25330			 *      function ( data, settings ) {
25331			 *        // Check the numeric part
25332			 *        if ( ! data.substring(1).match(/[0-9]/) ) {
25333			 *          return null;
25334			 *        }
25335			 *
25336			 *        // Check prefixed by currency
25337			 *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
25338			 *          return 'currency';
25339			 *        }
25340			 *        return null;
25341			 *      }
25342			 *    );
25343			 */
25344			detect: [],
25345	
25346	
25347			/**
25348			 * Type based search formatting.
25349			 *
25350			 * The type based searching functions can be used to pre-format the
25351			 * data to be search on. For example, it can be used to strip HTML
25352			 * tags or to de-format telephone numbers for numeric only searching.
25353			 *
25354			 * Note that is a search is not defined for a column of a given type,
25355			 * no search formatting will be performed.
25356			 * 
25357			 * Pre-processing of searching data plug-ins - When you assign the sType
25358			 * for a column (or have it automatically detected for you by DataTables
25359			 * or a type detection plug-in), you will typically be using this for
25360			 * custom sorting, but it can also be used to provide custom searching
25361			 * by allowing you to pre-processing the data and returning the data in
25362			 * the format that should be searched upon. This is done by adding
25363			 * functions this object with a parameter name which matches the sType
25364			 * for that target column. This is the corollary of <i>afnSortData</i>
25365			 * for searching data.
25366			 *
25367			 * The functions defined take a single parameter:
25368			 *
25369		     *  1. `{*}` Data from the column cell to be prepared for searching
25370			 *
25371			 * Each function is expected to return:
25372			 *
25373			 * * `{string|null}` Formatted string that will be used for the searching.
25374			 *
25375			 *  @type object
25376			 *  @default {}
25377			 *
25378			 *  @example
25379			 *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
25380			 *      return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
25381			 *    }
25382			 */
25383			search: {},
25384	
25385	
25386			/**
25387			 * Type based ordering.
25388			 *
25389			 * The column type tells DataTables what ordering to apply to the table
25390			 * when a column is sorted upon. The order for each type that is defined,
25391			 * is defined by the functions available in this object.
25392			 *
25393			 * Each ordering option can be described by three properties added to
25394			 * this object:
25395			 *
25396			 * * `{type}-pre` - Pre-formatting function
25397			 * * `{type}-asc` - Ascending order function
25398			 * * `{type}-desc` - Descending order function
25399			 *
25400			 * All three can be used together, only `{type}-pre` or only
25401			 * `{type}-asc` and `{type}-desc` together. It is generally recommended
25402			 * that only `{type}-pre` is used, as this provides the optimal
25403			 * implementation in terms of speed, although the others are provided
25404			 * for compatibility with existing Javascript sort functions.
25405			 *
25406			 * `{type}-pre`: Functions defined take a single parameter:
25407			 *
25408		     *  1. `{*}` Data from the column cell to be prepared for ordering
25409			 *
25410			 * And return:
25411			 *
25412			 * * `{*}` Data to be sorted upon
25413			 *
25414			 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
25415			 * functions, taking two parameters:
25416			 *
25417		     *  1. `{*}` Data to compare to the second parameter
25418		     *  2. `{*}` Data to compare to the first parameter
25419			 *
25420			 * And returning:
25421			 *
25422			 * * `{*}` Ordering match: <0 if first parameter should be sorted lower
25423			 *   than the second parameter, ===0 if the two parameters are equal and
25424			 *   >0 if the first parameter should be sorted height than the second
25425			 *   parameter.
25426			 * 
25427			 *  @type object
25428			 *  @default {}
25429			 *
25430			 *  @example
25431			 *    // Numeric ordering of formatted numbers with a pre-formatter
25432			 *    $.extend( $.fn.dataTable.ext.type.order, {
25433			 *      "string-pre": function(x) {
25434			 *        a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
25435			 *        return parseFloat( a );
25436			 *      }
25437			 *    } );
25438			 *
25439			 *  @example
25440			 *    // Case-sensitive string ordering, with no pre-formatting method
25441			 *    $.extend( $.fn.dataTable.ext.order, {
25442			 *      "string-case-asc": function(x,y) {
25443			 *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
25444			 *      },
25445			 *      "string-case-desc": function(x,y) {
25446			 *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
25447			 *      }
25448			 *    } );
25449			 */
25450			order: {}
25451		},
25452	
25453		/**
25454		 * Unique DataTables instance counter
25455		 *
25456		 * @type int
25457		 * @private
25458		 */
25459		_unique: 0,
25460	
25461	
25462		//
25463		// Depreciated
25464		// The following properties are retained for backwards compatibility only.
25465		// The should not be used in new projects and will be removed in a future
25466		// version
25467		//
25468	
25469		/**
25470		 * Version check function.
25471		 *  @type function
25472		 *  @depreciated Since 1.10
25473		 */
25474		fnVersionCheck: DataTable.fnVersionCheck,
25475	
25476	
25477		/**
25478		 * Index for what 'this' index API functions should use
25479		 *  @type int
25480		 *  @deprecated Since v1.10
25481		 */
25482		iApiIndex: 0,
25483	
25484	
25485		/**
25486		 * jQuery UI class container
25487		 *  @type object
25488		 *  @deprecated Since v1.10
25489		 */
25490		oJUIClasses: {},
25491	
25492	
25493		/**
25494		 * Software version
25495		 *  @type string
25496		 *  @deprecated Since v1.10
25497		 */
25498		sVersion: DataTable.version
25499	};
25500	
25501	
25502	//
25503	// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
25504	//
25505	$.extend( _ext, {
25506		afnFiltering: _ext.search,
25507		aTypes:       _ext.type.detect,
25508		ofnSearch:    _ext.type.search,
25509		oSort:        _ext.type.order,
25510		afnSortData:  _ext.order,
25511		aoFeatures:   _ext.feature,
25512		oApi:         _ext.internal,
25513		oStdClasses:  _ext.classes,
25514		oPagination:  _ext.pager
25515	} );
25516	
25517	
25518	$.extend( DataTable.ext.classes, {
25519		"sTable": "dataTable",
25520		"sNoFooter": "no-footer",
25521	
25522		/* Paging buttons */
25523		"sPageButton": "paginate_button",
25524		"sPageButtonActive": "current",
25525		"sPageButtonDisabled": "disabled",
25526	
25527		/* Striping classes */
25528		"sStripeOdd": "odd",
25529		"sStripeEven": "even",
25530	
25531		/* Empty row */
25532		"sRowEmpty": "dataTables_empty",
25533	
25534		/* Features */
25535		"sWrapper": "dataTables_wrapper",
25536		"sFilter": "dataTables_filter",
25537		"sInfo": "dataTables_info",
25538		"sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
25539		"sLength": "dataTables_length",
25540		"sProcessing": "dataTables_processing",
25541	
25542		/* Sorting */
25543		"sSortAsc": "sorting_asc",
25544		"sSortDesc": "sorting_desc",
25545		"sSortable": "sorting", /* Sortable in both directions */
25546		"sSortableAsc": "sorting_desc_disabled",
25547		"sSortableDesc": "sorting_asc_disabled",
25548		"sSortableNone": "sorting_disabled",
25549		"sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
25550	
25551		/* Filtering */
25552		"sFilterInput": "",
25553	
25554		/* Page length */
25555		"sLengthSelect": "",
25556	
25557		/* Scrolling */
25558		"sScrollWrapper": "dataTables_scroll",
25559		"sScrollHead": "dataTables_scrollHead",
25560		"sScrollHeadInner": "dataTables_scrollHeadInner",
25561		"sScrollBody": "dataTables_scrollBody",
25562		"sScrollFoot": "dataTables_scrollFoot",
25563		"sScrollFootInner": "dataTables_scrollFootInner",
25564	
25565		/* Misc */
25566		"sHeaderTH": "",
25567		"sFooterTH": "",
25568	
25569		// Deprecated
25570		"sSortJUIAsc": "",
25571		"sSortJUIDesc": "",
25572		"sSortJUI": "",
25573		"sSortJUIAscAllowed": "",
25574		"sSortJUIDescAllowed": "",
25575		"sSortJUIWrapper": "",
25576		"sSortIcon": "",
25577		"sJUIHeader": "",
25578		"sJUIFooter": ""
25579	} );
25580	
25581	
25582	var extPagination = DataTable.ext.pager;
25583	
25584	function _numbers ( page, pages ) {
25585		var
25586			numbers = [],
25587			buttons = extPagination.numbers_length,
25588			half = Math.floor( buttons / 2 ),
25589			i = 1;
25590	
25591		if ( pages <= buttons ) {
25592			numbers = _range( 0, pages );
25593		}
25594		else if ( page <= half ) {
25595			numbers = _range( 0, buttons-2 );
25596			numbers.push( 'ellipsis' );
25597			numbers.push( pages-1 );
25598		}
25599		else if ( page >= pages - 1 - half ) {
25600			numbers = _range( pages-(buttons-2), pages );
25601			numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
25602			numbers.splice( 0, 0, 0 );
25603		}
25604		else {
25605			numbers = _range( page-half+2, page+half-1 );
25606			numbers.push( 'ellipsis' );
25607			numbers.push( pages-1 );
25608			numbers.splice( 0, 0, 'ellipsis' );
25609			numbers.splice( 0, 0, 0 );
25610		}
25611	
25612		numbers.DT_el = 'span';
25613		return numbers;
25614	}
25615	
25616	
25617	$.extend( extPagination, {
25618		simple: function ( page, pages ) {
25619			return [ 'previous', 'next' ];
25620		},
25621	
25622		full: function ( page, pages ) {
25623			return [  'first', 'previous', 'next', 'last' ];
25624		},
25625	
25626		numbers: function ( page, pages ) {
25627			return [ _numbers(page, pages) ];
25628		},
25629	
25630		simple_numbers: function ( page, pages ) {
25631			return [ 'previous', _numbers(page, pages), 'next' ];
25632		},
25633	
25634		full_numbers: function ( page, pages ) {
25635			return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
25636		},
25637		
25638		first_last_numbers: function (page, pages) {
25639	 		return ['first', _numbers(page, pages), 'last'];
25640	 	},
25641	
25642		// For testing and plug-ins to use
25643		_numbers: _numbers,
25644	
25645		// Number of number buttons (including ellipsis) to show. _Must be odd!_
25646		numbers_length: 7
25647	} );
25648	
25649	
25650	$.extend( true, DataTable.ext.renderer, {
25651		pageButton: {
25652			_: function ( settings, host, idx, buttons, page, pages ) {
25653				var classes = settings.oClasses;
25654				var lang = settings.oLanguage.oPaginate;
25655				var aria = settings.oLanguage.oAria.paginate || {};
25656				var btnDisplay, btnClass
vendor: 17,892 bytes, lines 25656-26294
25656, counter=0;
25657	
25658				var attach = function( container, buttons ) {
25659					var i, ien, node, button, tabIndex;
25660					var disabledClass = classes.sPageButtonDisabled;
25661					var clickHandler = function ( e ) {
25662						_fnPageChange( settings, e.data.action, true );
25663					};
25664	
25665					for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
25666						button = buttons[i];
25667	
25668						if ( Array.isArray( button ) ) {
25669							var inner = $( '<'+(button.DT_el || 'div')+'/>' )
25670								.appendTo( container );
25671							attach( inner, button );
25672						}
25673						else {
25674							btnDisplay = null;
25675							btnClass = button;
25676							tabIndex = settings.iTabIndex;
25677	
25678							switch ( button ) {
25679								case 'ellipsis':
25680									container.append('<span class="ellipsis">&#x2026;</span>');
25681									break;
25682	
25683								case 'first':
25684									btnDisplay = lang.sFirst;
25685	
25686									if ( page === 0 ) {
25687										tabIndex = -1;
25688										btnClass += ' ' + disabledClass;
25689									}
25690									break;
25691	
25692								case 'previous':
25693									btnDisplay = lang.sPrevious;
25694	
25695									if ( page === 0 ) {
25696										tabIndex = -1;
25697										btnClass += ' ' + disabledClass;
25698									}
25699									break;
25700	
25701								case 'next':
25702									btnDisplay = lang.sNext;
25703	
25704									if ( pages === 0 || page === pages-1 ) {
25705										tabIndex = -1;
25706										btnClass += ' ' + disabledClass;
25707									}
25708									break;
25709	
25710								case 'last':
25711									btnDisplay = lang.sLast;
25712	
25713									if ( pages === 0 || page === pages-1 ) {
25714										tabIndex = -1;
25715										btnClass += ' ' + disabledClass;
25716									}
25717									break;
25718	
25719								default:
25720									btnDisplay = settings.fnFormatNumber( button + 1 );
25721									btnClass = page === button ?
25722										classes.sPageButtonActive : '';
25723									break;
25724							}
25725	
25726							if ( btnDisplay !== null ) {
25727								node = $('<a>', {
25728										'class': classes.sPageButton+' '+btnClass,
25729										'aria-controls': settings.sTableId,
25730										'aria-label': aria[ button ],
25731										'data-dt-idx': counter,
25732										'tabindex': tabIndex,
25733										'id': idx === 0 && typeof button === 'string' ?
25734											settings.sTableId +'_'+ button :
25735											null
25736									} )
25737									.html( btnDisplay )
25738									.appendTo( container );
25739	
25740								_fnBindAction(
25741									node, {action: button}, clickHandler
25742								);
25743	
25744								counter++;
25745							}
25746						}
25747					}
25748				};
25749	
25750				// IE9 throws an 'unknown error' if document.activeElement is used
25751				// inside an iframe or frame. Try / catch the error. Not good for
25752				// accessibility, but neither are frames.
25753				var activeEl;
25754	
25755				try {
25756					// Because this approach is destroying and recreating the paging
25757					// elements, focus is lost on the select button which is bad for
25758					// accessibility. So we want to restore focus once the draw has
25759					// completed
25760					activeEl = $(host).find(document.activeElement).data('dt-idx');
25761				}
25762				catch (e) {}
25763	
25764				attach( $(host).empty(), buttons );
25765	
25766				if ( activeEl !== undefined ) {
25767					$(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');
25768				}
25769			}
25770		}
25771	} );
25772	
25773	
25774	
25775	// Built in type detection. See model.ext.aTypes for information about
25776	// what is required from this methods.
25777	$.extend( DataTable.ext.type.detect, [
25778		// Plain numbers - first since V8 detects some plain numbers as dates
25779		// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
25780		function ( d, settings )
25781		{
25782			var decimal = settings.oLanguage.sDecimal;
25783			return _isNumber( d, decimal ) ? 'num'+decimal : null;
25784		},
25785	
25786		// Dates (only those recognised by the browser's Date.parse)
25787		function ( d, settings )
25788		{
25789			// V8 tries _very_ hard to make a string passed into `Date.parse()`
25790			// valid, so we need to use a regex to restrict date formats. Use a
25791			// plug-in for anything other than ISO8601 style strings
25792			if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
25793				return null;
25794			}
25795			var parsed = Date.parse(d);
25796			return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
25797		},
25798	
25799		// Formatted numbers
25800		function ( d, settings )
25801		{
25802			var decimal = settings.oLanguage.sDecimal;
25803			return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
25804		},
25805	
25806		// HTML numeric
25807		function ( d, settings )
25808		{
25809			var decimal = settings.oLanguage.sDecimal;
25810			return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
25811		},
25812	
25813		// HTML numeric, formatted
25814		function ( d, settings )
25815		{
25816			var decimal = settings.oLanguage.sDecimal;
25817			return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
25818		},
25819	
25820		// HTML (this is strict checking - there must be html)
25821		function ( d, settings )
25822		{
25823			return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
25824				'html' : null;
25825		}
25826	] );
25827	
25828	
25829	
25830	// Filter formatting functions. See model.ext.ofnSearch for information about
25831	// what is required from these methods.
25832	// 
25833	// Note that additional search methods are added for the html numbers and
25834	// html formatted numbers by `_addNumericSort()` when we know what the decimal
25835	// place is
25836	
25837	
25838	$.extend( DataTable.ext.type.search, {
25839		html: function ( data ) {
25840			return _empty(data) ?
25841				data :
25842				typeof data === 'string' ?
25843					data
25844						.replace( _re_new_lines, " " )
25845						.replace( _re_html, "" ) :
25846					'';
25847		},
25848	
25849		string: function ( data ) {
25850			return _empty(data) ?
25851				data :
25852				typeof data === 'string' ?
25853					data.replace( _re_new_lines, " " ) :
25854					data;
25855		}
25856	} );
25857	
25858	
25859	
25860	var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
25861		if ( d !== 0 && (!d || d === '-') ) {
25862			return -Infinity;
25863		}
25864	
25865		// If a decimal place other than `.` is used, it needs to be given to the
25866		// function so we can detect it and replace with a `.` which is the only
25867		// decimal place Javascript recognises - it is not locale aware.
25868		if ( decimalPlace ) {
25869			d = _numToDecimal( d, decimalPlace );
25870		}
25871	
25872		if ( d.replace ) {
25873			if ( re1 ) {
25874				d = d.replace( re1, '' );
25875			}
25876	
25877			if ( re2 ) {
25878				d = d.replace( re2, '' );
25879			}
25880		}
25881	
25882		return d * 1;
25883	};
25884	
25885	
25886	// Add the numeric 'deformatting' functions for sorting and search. This is done
25887	// in a function to provide an easy ability for the language options to add
25888	// additional methods if a non-period decimal place is used.
25889	function _addNumericSort ( decimalPlace ) {
25890		$.each(
25891			{
25892				// Plain numbers
25893				"num": function ( d ) {
25894					return __numericReplace( d, decimalPlace );
25895				},
25896	
25897				// Formatted numbers
25898				"num-fmt": function ( d ) {
25899					return __numericReplace( d, decimalPlace, _re_formatted_numeric );
25900				},
25901	
25902				// HTML numeric
25903				"html-num": function ( d ) {
25904					return __numericReplace( d, decimalPlace, _re_html );
25905				},
25906	
25907				// HTML numeric, formatted
25908				"html-num-fmt": function ( d ) {
25909					return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
25910				}
25911			},
25912			function ( key, fn ) {
25913				// Add the ordering method
25914				_ext.type.order[ key+decimalPlace+'-pre' ] = fn;
25915	
25916				// For HTML types add a search formatter that will strip the HTML
25917				if ( key.match(/^html\-/) ) {
25918					_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
25919				}
25920			}
25921		);
25922	}
25923	
25924	
25925	// Default sort methods
25926	$.extend( _ext.type.order, {
25927		// Dates
25928		"date-pre": function ( d ) {
25929			var ts = Date.parse( d );
25930			return isNaN(ts) ? -Infinity : ts;
25931		},
25932	
25933		// html
25934		"html-pre": function ( a ) {
25935			return _empty(a) ?
25936				'' :
25937				a.replace ?
25938					a.replace( /<.*?>/g, "" ).toLowerCase() :
25939					a+'';
25940		},
25941	
25942		// string
25943		"string-pre": function ( a ) {
25944			// This is a little complex, but faster than always calling toString,
25945			// http://jsperf.com/tostring-v-check
25946			return _empty(a) ?
25947				'' :
25948				typeof a === 'string' ?
25949					a.toLowerCase() :
25950					! a.toString ?
25951						'' :
25952						a.toString();
25953		},
25954	
25955		// string-asc and -desc are retained only for compatibility with the old
25956		// sort methods
25957		"string-asc": function ( x, y ) {
25958			return ((x < y) ? -1 : ((x > y) ? 1 : 0));
25959		},
25960	
25961		"string-desc": function ( x, y ) {
25962			return ((x < y) ? 1 : ((x > y) ? -1 : 0));
25963		}
25964	} );
25965	
25966	
25967	// Numeric sorting types - order doesn't matter here
25968	_addNumericSort( '' );
25969	
25970	
25971	$.extend( true, DataTable.ext.renderer, {
25972		header: {
25973			_: function ( settings, cell, column, classes ) {
25974				// No additional mark-up required
25975				// Attach a sort listener to update on sort - note that using the
25976				// `DT` namespace will allow the event to be removed automatically
25977				// on destroy, while the `dt` namespaced event is the one we are
25978				// listening for
25979				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
25980					if ( settings !== ctx ) { // need to check this this is the host
25981						return;               // table, not a nested one
25982					}
25983	
25984					var colIdx = column.idx;
25985	
25986					cell
25987						.removeClass(
25988							classes.sSortAsc +' '+
25989							classes.sSortDesc
25990						)
25991						.addClass( columns[ colIdx ] == 'asc' ?
25992							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
25993								classes.sSortDesc :
25994								column.sSortingClass
25995						);
25996				} );
25997			},
25998	
25999			jqueryui: function ( settings, cell, column, classes ) {
26000				$('<div/>')
26001					.addClass( classes.sSortJUIWrapper )
26002					.append( cell.contents() )
26003					.append( $('<span/>')
26004						.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
26005					)
26006					.appendTo( cell );
26007	
26008				// Attach a sort listener to update on sort
26009				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
26010					if ( settings !== ctx ) {
26011						return;
26012					}
26013	
26014					var colIdx = column.idx;
26015	
26016					cell
26017						.removeClass( classes.sSortAsc +" "+classes.sSortDesc )
26018						.addClass( columns[ colIdx ] == 'asc' ?
26019							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
26020								classes.sSortDesc :
26021								column.sSortingClass
26022						);
26023	
26024					cell
26025						.find( 'span.'+classes.sSortIcon )
26026						.removeClass(
26027							classes.sSortJUIAsc +" "+
26028							classes.sSortJUIDesc +" "+
26029							classes.sSortJUI +" "+
26030							classes.sSortJUIAscAllowed +" "+
26031							classes.sSortJUIDescAllowed
26032						)
26033						.addClass( columns[ colIdx ] == 'asc' ?
26034							classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
26035								classes.sSortJUIDesc :
26036								column.sSortingClassJUI
26037						);
26038				} );
26039			}
26040		}
26041	} );
26042	
26043	/*
26044	 * Public helper functions. These aren't used internally by DataTables, or
26045	 * called by any of the options passed into DataTables, but they can be used
26046	 * externally by developers working with DataTables. They are helper functions
26047	 * to make working with DataTables a little bit easier.
26048	 */
26049	
26050	var __htmlEscapeEntities = function ( d ) {
26051		if (Array.isArray(d)) {
26052			d = d.join(',');
26053		}
26054	
26055		return typeof d === 'string' ?
26056			d
26057				.replace(/&/g, '&amp;')
26058				.replace(/</g, '&lt;')
26059				.replace(/>/g, '&gt;')
26060				.replace(/"/g, '&quot;') :
26061			d;
26062	};
26063	
26064	/**
26065	 * Helpers for `columns.render`.
26066	 *
26067	 * The options defined here can be used with the `columns.render` initialisation
26068	 * option to provide a display renderer. The following functions are defined:
26069	 *
26070	 * * `number` - Will format numeric data (defined by `columns.data`) for
26071	 *   display, retaining the original unformatted data for sorting and filtering.
26072	 *   It takes 5 parameters:
26073	 *   * `string` - Thousands grouping separator
26074	 *   * `string` - Decimal point indicator
26075	 *   * `integer` - Number of decimal points to show
26076	 *   * `string` (optional) - Prefix.
26077	 *   * `string` (optional) - Postfix (/suffix).
26078	 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
26079	 *   parameters.
26080	 *
26081	 * @example
26082	 *   // Column definition using the number renderer
26083	 *   {
26084	 *     data: "salary",
26085	 *     render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
26086	 *   }
26087	 *
26088	 * @namespace
26089	 */
26090	DataTable.render = {
26091		number: function ( thousands, decimal, precision, prefix, postfix ) {
26092			return {
26093				display: function ( d ) {
26094					if ( typeof d !== 'number' && typeof d !== 'string' ) {
26095						return d;
26096					}
26097	
26098					var negative = d < 0 ? '-' : '';
26099					var flo = parseFloat( d );
26100	
26101					// If NaN then there isn't much formatting that we can do - just
26102					// return immediately, escaping any HTML (this was supposed to
26103					// be a number after all)
26104					if ( isNaN( flo ) ) {
26105						return __htmlEscapeEntities( d );
26106					}
26107	
26108					flo = flo.toFixed( precision );
26109					d = Math.abs( flo );
26110	
26111					var intPart = parseInt( d, 10 );
26112					var floatPart = precision ?
26113						decimal+(d - intPart).toFixed( precision ).substring( 2 ):
26114						'';
26115	
26116					// If zero, then can't have a negative prefix
26117					if (intPart === 0 && parseFloat(floatPart) === 0) {
26118						negative = '';
26119					}
26120	
26121					return negative + (prefix||'') +
26122						intPart.toString().replace(
26123							/\B(?=(\d{3})+(?!\d))/g, thousands
26124						) +
26125						floatPart +
26126						(postfix||'');
26127				}
26128			};
26129		},
26130	
26131		text: function () {
26132			return {
26133				display: __htmlEscapeEntities,
26134				filter: __htmlEscapeEntities
26135			};
26136		}
26137	};
26138	
26139	
26140	/*
26141	 * This is really a good bit rubbish this method of exposing the internal methods
26142	 * publicly... - To be fixed in 2.0 using methods on the prototype
26143	 */
26144	
26145	
26146	/**
26147	 * Create a wrapper function for exporting an internal functions to an external API.
26148	 *  @param {string} fn API function name
26149	 *  @returns {function} wrapped function
26150	 *  @memberof DataTable#internal
26151	 */
26152	function _fnExternApiFunc (fn)
26153	{
26154		return function() {
26155			var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
26156				Array.prototype.slice.call(arguments)
26157			);
26158			return DataTable.ext.internal[fn].apply( this, args );
26159		};
26160	}
26161	
26162	
26163	/**
26164	 * Reference to internal functions for use by plug-in developers. Note that
26165	 * these methods are references to internal functions and are considered to be
26166	 * private. If you use these methods, be aware that they are liable to change
26167	 * between versions.
26168	 *  @namespace
26169	 */
26170	$.extend( DataTable.ext.internal, {
26171		_fnExternApiFunc: _fnExternApiFunc,
26172		_fnBuildAjax: _fnBuildAjax,
26173		_fnAjaxUpdate: _fnAjaxUpdate,
26174		_fnAjaxParameters: _fnAjaxParameters,
26175		_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
26176		_fnAjaxDataSrc: _fnAjaxDataSrc,
26177		_fnAddColumn: _fnAddColumn,
26178		_fnColumnOptions: _fnColumnOptions,
26179		_fnAdjustColumnSizing: _fnAdjustColumnSizing,
26180		_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
26181		_fnColumnIndexToVisible: _fnColumnIndexToVisible,
26182		_fnVisbleColumns: _fnVisbleColumns,
26183		_fnGetColumns: _fnGetColumns,
26184		_fnColumnTypes: _fnColumnTypes,
26185		_fnApplyColumnDefs: _fnApplyColumnDefs,
26186		_fnHungarianMap: _fnHungarianMap,
26187		_fnCamelToHungarian: _fnCamelToHungarian,
26188		_fnLanguageCompat: _fnLanguageCompat,
26189		_fnBrowserDetect: _fnBrowserDetect,
26190		_fnAddData: _fnAddData,
26191		_fnAddTr: _fnAddTr,
26192		_fnNodeToDataIndex: _fnNodeToDataIndex,
26193		_fnNodeToColumnIndex: _fnNodeToColumnIndex,
26194		_fnGetCellData: _fnGetCellData,
26195		_fnSetCellData: _fnSetCellData,
26196		_fnSplitObjNotation: _fnSplitObjNotation,
26197		_fnGetObjectDataFn: _fnGetObjectDataFn,
26198		_fnSetObjectDataFn: _fnSetObjectDataFn,
26199		_fnGetDataMaster: _fnGetDataMaster,
26200		_fnClearTable: _fnClearTable,
26201		_fnDeleteIndex: _fnDeleteIndex,
26202		_fnInvalidate: _fnInvalidate,
26203		_fnGetRowElements: _fnGetRowElements,
26204		_fnCreateTr: _fnCreateTr,
26205		_fnBuildHead: _fnBuildHead,
26206		_fnDrawHead: _fnDrawHead,
26207		_fnDraw: _fnDraw,
26208		_fnReDraw: _fnReDraw,
26209		_fnAddOptionsHtml: _fnAddOptionsHtml,
26210		_fnDetectHeader: _fnDetectHeader,
26211		_fnGetUniqueThs: _fnGetUniqueThs,
26212		_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
26213		_fnFilterComplete: _fnFilterComplete,
26214		_fnFilterCustom: _fnFilterCustom,
26215		_fnFilterColumn: _fnFilterColumn,
26216		_fnFilter: _fnFilter,
26217		_fnFilterCreateSearch: _fnFilterCreateSearch,
26218		_fnEscapeRegex: _fnEscapeRegex,
26219		_fnFilterData: _fnFilterData,
26220		_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
26221		_fnUpdateInfo: _fnUpdateInfo,
26222		_fnInfoMacros: _fnInfoMacros,
26223		_fnInitialise: _fnInitialise,
26224		_fnInitComplete: _fnInitComplete,
26225		_fnLengthChange: _fnLengthChange,
26226		_fnFeatureHtmlLength: _fnFeatureHtmlLength,
26227		_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
26228		_fnPageChange: _fnPageChange,
26229		_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
26230		_fnProcessingDisplay: _fnProcessingDisplay,
26231		_fnFeatureHtmlTable: _fnFeatureHtmlTable,
26232		_fnScrollDraw: _fnScrollDraw,
26233		_fnApplyToChildren: _fnApplyToChildren,
26234		_fnCalculateColumnWidths: _fnCalculateColumnWidths,
26235		_fnThrottle: _fnThrottle,
26236		_fnConvertToWidth: _fnConvertToWidth,
26237		_fnGetWidestNode: _fnGetWidestNode,
26238		_fnGetMaxLenString: _fnGetMaxLenString,
26239		_fnStringToCss: _fnStringToCss,
26240		_fnSortFlatten: _fnSortFlatten,
26241		_fnSort: _fnSort,
26242		_fnSortAria: _fnSortAria,
26243		_fnSortListener: _fnSortListener,
26244		_fnSortAttachListener: _fnSortAttachListener,
26245		_fnSortingClasses: _fnSortingClasses,
26246		_fnSortData: _fnSortData,
26247		_fnSaveState: _fnSaveState,
26248		_fnLoadState: _fnLoadState,
26249		_fnImplementState: _fnImplementState,
26250		_fnSettingsFromNode: _fnSettingsFromNode,
26251		_fnLog: _fnLog,
26252		_fnMap: _fnMap,
26253		_fnBindAction: _fnBindAction,
26254		_fnCallbackReg: _fnCallbackReg,
26255		_fnCallbackFire: _fnCallbackFire,
26256		_fnLengthOverflow: _fnLengthOverflow,
26257		_fnRenderer: _fnRenderer,
26258		_fnDataSource: _fnDataSource,
26259		_fnRowAttributes: _fnRowAttributes,
26260		_fnExtend: _fnExtend,
26261		_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
26262		                                // in 1.10, so this dead-end function is
26263		                                // added to prevent errors
26264	} );
26265	
26266
26267	// jQuery access
26268	$.fn.dataTable = DataTable;
26269
26270	// Provide access to the host jQuery object (circular reference)
26271	DataTable.$ = $;
26272
26273	// Legacy aliases
26274	$.fn.dataTableSettings = DataTable.settings;
26275	$.fn.dataTableExt = DataTable.ext;
26276
26277	// With a capital `D` we return a DataTables API instance rather than a
26278	// jQuery object
26279	$.fn.DataTable = function ( opts ) {
26280		return $(this).dataTable( opts ).api();
26281	};
26282
26283	// All properties that are available to $.fn.dataTable should also be
26284	// available on $.fn.DataTable
26285	$.each( DataTable, function ( prop, val ) {
26286		$.fn.DataTable[ prop ] = val;
26287	} );
26288
26289	return DataTable;
26290}));
26291
26292
26293/***/ }),
26294/* 2 */
vendor: 16,174 bytes, lines 26295-26323
26295/***/ (function(module, exports) {
26296
26297var g;
26298
26299// This works in non-strict mode
26300g = (function() {
26301	return this;
26302})();
26303
26304try {
26305	// This works if eval is allowed (see CSP)
26306	g = g || new Function("return this")();
26307} catch (e) {
26308	// This works if the window reference is available
26309	if (typeof window === "object") g = window;
26310}
26311
26312// g can still be undefined, but nothing to do about it...
26313// We return undefined, instead of nothing here, so it's
26314// easier to handle this case. if(!global) { ...}
26315
26316module.exports = g;
26317
26318
26319/***/ }),
26320/* 3 */
26321/***/ (function(module, exports, __webpack_require__) {
26322
26323!function(e,t){ true?module.exports=t():undefined}(window,(function(){return function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);var a=[],r=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],i=["January","February","March","April","May","June","July","August","September","October","November","December"],o={t:"top",r:"right",b:"bottom",l:"left",c:"centered"};function s(){}var l=["click","focusin","keydown","input"];function d(e){l.forEach((function(t){e.addEventListener(t,e===document?L:Y)}))}function c(e){return Array.isArray(e)?e.map(c):"[object Object]"===x(e)?Object.keys(e).reduce((function(t,n){return t[n]=c(e[n]),t}),{}):e}function u(e,t){var n=e.calendar.querySelector(".qs-overlay"),a=n&&!n.classList.contains("qs-hidden");t=t||new Date(e.currentYear,e.currentMonth),e.calendar.innerHTML=[h(t,e,a),f(t,e,a),v(e,a)].join(""),a&&window.requestAnimationFrame((function(){M(!0,e)}))}function h(e,t,n){return['<div class="qs-controls'+(n?" qs-blur":"")+'">','<div class="qs-arrow qs-left"></div>','<div class="qs-month-year">','<span class="qs-month">'+t.months[e.getMonth()]+"</span>",'<span class="qs-year">'+e.getFullYear()+"</span>","</div>",'<div class="qs-arrow qs-right"></div>',"</div>"].join("")}function f(e,t,n){var a=t.currentMonth,r=t.currentYear,i=t.dateSelected,o=t.maxDate,s=t.minDate,l=t.showAllDates,d=t.days,c=t.disabledDates,u=t.startDay,h=t.weekendIndices,f=t.events,v=t.getRange?t.getRange():{},m=+v.start,y=+v.end,p=g(new Date(e).setDate(1)),w=p.getDay()-u,D=w<0?7:0;p.setMonth(p.getMonth()+1),p.setDate(0);var b=p.getDate(),q=[],S=D+7*((w+b)/7|0);S+=(w+b)%7?7:0;for(var M=1;M<=S;M++){var E=(M-1)%7,x=d[E],C=M-(w>=0?w:7+w),L=new Date(r,a,C),Y=f[+L],j=C<1||C>b,P=j?C<1?-1:1:0,k=j&&!l,O=k?"":L.getDate(),N=+L==+i,_=E===h[0]||E===h[1],I=m!==y,A="qs-square "+x;Y&&!k&&(A+=" qs-event"),j&&(A+=" qs-outside-current-month"),!l&&j||(A+=" qs-num"),N&&(A+=" qs-active"),(c[+L]||t.disabler(L)||_&&t.noWeekends||s&&+L<+s||o&&+L>+o)&&!k&&(A+=" qs-disabled"),+g(new Date)==+L&&(A+=" qs-current"),+L===m&&y&&I&&(A+=" qs-range-start"),+L>m&&+L<y&&(A+=" qs-range-middle"),+L===y&&m&&I&&(A+=" qs-range-end"),k&&(A+=" qs-empty",O=""),q.push('<div class="'+A+'" data-direction="'+P+'">'+O+"</div>")}var R=d.map((function(e){return'<div class="qs-square qs-day">'+e+"</div>"})).concat(q);return R.unshift('<div class="qs-squares'+(n?" qs-blur":"")+'">'),R.push("</div>"),R.join("")}function v(e,t){var n=e.overlayPlaceholder,a=e.overlayButton;return['<div class="qs-overlay'+(t?"":" qs-hidden")+'">',"<div>",'<input class="qs-overlay-year" placeholder="'+n+'" inputmode="numeric" />','<div class="qs-close">&#10005;</div>',"</div>",'<div class="qs-overlay-month-container">'+e.overlayMonths.map((function(e,t){return'<div class="qs-overlay-month" data-month-num="'+t+'">'+e+"</div>"})).join("")+"</div>",'<div class="qs-submit qs-disabled">'+a+"</div>","</div>"].join("")}function m(e,t,n){var a=t.el,r=t.calendar.querySelector(".qs-active"),i=e.textContent,o=t.sibling;(a.disabled||a.readOnly)&&t.respectDisabledReadOnly||(t.dateSelected=n?void 0:new Date(t.currentYear,t.currentMonth,i),r&&r.classList.remove("qs-active"),n||e.classList.add("qs-active"),p(a,t,n),n||q(t),o&&(y({instance:t,deselect:n}),t.first&&!o.dateSelected&&(o.currentYear=t.currentYear,o.currentMonth=t.currentMonth,o.currentMonthName=t.currentMonthName),u(t),u(o)),t.onSelect(t,n?void 0:new Date(t.dateSelected)))}function y(e){var t=e.instance.first?e.instance:e.instance.sibling,n=t.sibling;t===e.instance?e.deselect?(t.minDate=t.originalMinDate,n.minDate=n.originalMinDate):n.minDate=t.dateSelected:e.deselect?(n.maxDate=n.originalMaxDate,t.maxDate=t.originalMaxDate):t.maxDate=n.dateSelected}function p(e,t,n){if(!t.nonInput)return n?e.value="":t.formatter!==s?t.formatter(e,t.dateSelected,t):void(e.value=t.dateSelected.toDateString())}function w(e,t,n,a){n||a?(n&&(t.currentYear=+n),a&&(t.currentMonth=+a)):(t.currentMonth+=e.contains("qs-right")?1:-1,12===t.currentMonth?(t.currentMonth=0,t.currentYear++):-1===t.currentMonth&&(t.currentMonth=11,t.currentYear--)),t.currentMonthName=t.months[t.currentMonth],u(t),t.onMonthChange(t)}function D(e){if(!e.noPosition){var t=e.position.top,n=e.position.right;if(e.position.centered)return e.calendarContainer.classList.add("qs-centered");var a=e.positionedEl.getBoundingClientRect(),r=e.el.getBoundingClientRect(),i=e.calendarContainer.getBoundingClientRect(),o=r.top-a.top+(t?-1*i.height:r.height)+"px",s=r.left-a.left+(n?r.width-i.width:0)+"px";e.calendarContainer.style.setProperty("top",o),e.calendarContainer.style.setProperty("left",s)}}function b(e){return"[object Date]"===x(e)&&"Invalid Date"!==e.toString()}function g(e){if(b(e)||"number"==typeof e&&!isNaN(e)){var t=new Date(+e);return new Date(t.getFullYear(),t.getMonth(),t.getDate())}}function q(e){e.disabled||!e.calendarContainer.classList.contains("qs-hidden")&&!e.alwaysShow&&("overlay"!==e.defaultView&&M(!0,e),e.calendarContainer.classList.add("qs-hidden"),e.onHide(e))}function S(e){e.disabled||(e.calendarContainer.classList.remove("qs-hidden"),"overlay"===e.defaultView&&M(!1,e),D(e),e.onShow(e))}function M(e,t){var n=t.calendar,a=n.querySelector(".qs-overlay"),r=a.querySelector(".qs-overlay-year"),i=n.querySelector(".qs-controls"),o=n.querySelector(".qs-squares");e?(a.classList.add("qs-hidden"),i.classList.remove("qs-blur"),o.classList.remove("qs-blur"),r.value=""):(a.classList.remove("qs-hidden"),i.classList.add("qs-blur"),o.classList.add("qs-blur"),r.focus())}function E(e,t,n,a){var r=isNaN(+(new Date).setFullYear(t.value||void 0)),i=r?null:t.value;if(13===e.which||13===e.keyCode||"click"===e.type)a?w(null,n,i,a):r||t.classList.contains("qs-disabled")||w(null,n,i);else if(n.calendar.contains(t)){n.calendar.querySelector(".qs-submit").classList[r?"add":"remove"]("qs-disabled")}}function x(e){return{}.toString.call(e)}function C(e){a.forEach((function(t){t!==e&&q(t)}))}function L(e){if(!e.__qs_shadow_dom){var t=e.which||e.keyCode,n=e.type,r=e.target,o=r.classList,s=a.filter((function(e){return e.calendar.contains(r)||e.el===r}))[0],l=s&&s.calendar.contains(r);if(!(s&&s.isMobile&&s.disableMobile))if("click"===n){if(!s)return a.forEach(q);if(s.disabled)return;var d=s.calendar,c=s.calendarContainer,h=s.disableYearOverlay,f=s.nonInput,v=d.querySelector(".qs-overlay-year"),y=!!d.querySelector(".qs-hidden"),p=d.querySelector(".qs-month-year").contains(r),D=r.dataset.monthNum;if(s.noPosition&&!l)(c.classList.contains("qs-hidden")?S:q)(s);else if(o.contains("qs-arrow"))w(o,s);else if(p||o.contains("qs-close"))h||M(!y,s);else if(D)E(e,v,s,D);else{if(o.contains("qs-disabled"))return;if(o.contains("qs-num")){var b=r.textContent,g=+r.dataset.direction,x=new Date(s.currentYear,s.currentMonth+g,b);if(g){s.currentYear=x.getFullYear(),s.currentMonth=x.getMonth(),s.currentMonthName=i[s.currentMonth],u(s);for(var L,Y=s.calendar.querySelectorAll('[data-direction="0"]'),j=0;!L;){var P=Y[j];P.textContent===b&&(L=P),j++}r=L}return void(+x==+s.dateSelected?m(r,s,!0):r.classList.contains("qs-disabled")||m(r,s))}o.contains("qs-submit")?E(e,v,s):f&&r===s.el&&(S(s),C(s))}}else if("focusin"===n&&s)S(s),C(s);else if("keydown"===n&&9===t&&s)q(s);else if("keydown"===n&&s&&!s.disabled){var k=!s.calendar.querySelector(".qs-overlay").classList.contains("qs-hidden");13===t&&k&&l?E(e,r,s):27===t&&k&&l&&M(!0,s)}else if("input"===n){if(!s||!s.calendar.contains(r))return;var O=s.calendar.querySelector(".qs-submit"),N=r.value.split("").reduce((function(e,t){return e||"0"!==t?e+(t.match(/[0-9]/)?t:""):""}),"").slice(0,4);r.value=N,O.classList[4===N.length?"remove":"add"]("qs-disabled")}}}function Y(e){L(e),e.__qs_shadow_dom=!0}function j(e,t){l.forEach((function(n){e.removeEventListener(n,t)}))}function P(){S(this)}function k(){q(this)}function O(e,t){var n=g(e),a=this.currentYear,r=this.currentMonth,i=this.sibling;if(null==e)return this.dateSelected=void 0,p(this.el,this,!0),i&&(y({instance:this,deselect:!0}),u(i)),u(this),this;if(!b(e))throw new Error("`setDate` needs a JavaScript Date object.");if(this.disabledDates[+n]||n<this.minDate||n>this.maxDate)throw new Error("You can't manually set a date that's disabled.");this.dateSelected=n,t&&(this.currentYear=n.getFullYear(),this.currentMonth=n.getMonth(),this.currentMonthName=this.months[n.getMonth()]),p(this.el,this),i&&(y({instance:this}),u(i));var o=a===n.getFullYear()&&r===n.getMonth();return o||t?u(this,n):o||u(this,new Date(a,r,1)),this}function N(e){return I(this,e,!0)}function _(e){return I(this,e)}function I(e,t,n){var a=e.dateSelected,r=e.first,i=e.sibling,o=e.minDate,s=e.maxDate,l=g(t),d=n?"Min":"Max";function c(){return"original"+d+"Date"}function h(){return d.toLowerCase()+"Date"}function f(){return"set"+d}function v(){throw new Error("Out-of-range date passed to "+f())}if(null==t)e[c()]=void 0,i?(i[c()]=void 0,n?(r&&!a||!r&&!i.dateSelected)&&(e.minDate=void 0,i.minDate=void 0):(r&&!i.dateSelected||!r&&!a)&&(e.maxDate=void 0,i.maxDate=void 0)):e[h()]=void 0;else{if(!b(t))throw new Error("Invalid date passed to "+f());i?((r&&n&&l>(a||s)||r&&!n&&l<(i.dateSelected||o)||!r&&n&&l>(i.dateSelected||s)||!r&&!n&&l<(a||o))&&v(),e[c()]=l,i[c()]=l,(n&&(r&&!a||!r&&!i.dateSelected)||!n&&(r&&!i.dateSelected||!r&&!a))&&(e[h()]=l,i[h()]=l)):((n&&l>(a||s)||!n&&l<(a||o))&&v(),e[h()]=l)}return i&&u(i),u(e),e}function A(){var e=this.first?this:this.sibling,t=e.sibling;return{start:e.dateSelected,end:t.dateSelected}}function R(){var e=this.shadowDom,t=this.positionedEl,n=this.calendarContainer,r=this.sibling,i=this;this.inlinePosition&&(a.some((function(e){return e!==i&&e.positionedEl===t}))||t.style.setProperty("position",null));n.remove(),a=a.filter((function(e){return e!==i})),r&&delete r.sibling,a.length||j(document,L);var o=a.some((function(t){return t.shadowDom===e}));for(var s in e&&!o&&j(e,Y),this)delete this[s];a.length||l.forEach((function(e){document.removeEventListener(e,L)}))}function F(e,t){var n=new Date(e);if(!b(n))throw new Error("Invalid date passed to `navigate`");this.currentYear=n.getFullYear(),this.currentMonth=n.getMonth(),u(this),t&&this.onMonthChange(this)}function B(){var e=!this.calendarContainer.classList.contains("qs-hidden"),t=!this.calendarContainer.querySelector(".qs-overlay").classList.contains("qs-hidden");e&&M(t,this)}t.default=function(e,t){var n=function(e,t){var n,l,d=function(e){var t=c(e);t.events&&(t.events=t.events.reduce((function(e,t){if(!b(t))throw new Error('"options.events" must only contain valid JavaScript Date objects.');return e[+g(t)]=!0,e}),{}));["startDate","dateSelected","minDate","maxDate"].forEach((function(e){var n=t[e];if(n&&!b(n))throw new Error('"options.'+e+'" needs to be a valid JavaScript Date object.');t[e]=g(n)}));var n=t.position,i=t.maxDate,l=t.minDate,d=t.dateSelected,u=t.overlayPlaceholder,h=t.overlayButton,f=t.startDay,v=t.id;if(t.startDate=g(t.startDate||d||new Date),t.disabledDates=(t.disabledDates||[]).reduce((function(e,t){var n=+g(t);if(!b(t))throw new Error('You supplied an invalid date to "options.disabledDates".');if(n===+g(d))throw new Error('"disabledDates" cannot contain the same date as "dateSelected".');return e[n]=1,e}),{}),t.hasOwnProperty("id")&&null==v)throw new Error("`id` cannot be `null` or `undefined`");if(null!=v){var m=a.filter((function(e){return e.id===v}));if(m.length>1)throw new Error("Only two datepickers can share an id.");m.length?(t.second=!0,t.sibling=m[0]):t.first=!0}var y=["tr","tl","br","bl","c"].some((function(e){return n===e}));if(n&&!y)throw new Error('"options.position" must be one of the following: tl, tr, bl, br, or c.');function p(e){throw new Error('"dateSelected" in options is '+(e?"less":"greater")+' than "'+(e||"max")+'Date".')}if(t.position=function(e){var t=e[0],n=e[1],a={};a[o[t]]=1,n&&(a[o[n]]=1);return a}(n||"bl"),i<l)throw new Error('"maxDate" in options is less than "minDate".');d&&(l>d&&p("min"),i<d&&p());if(["onSelect","onShow","onHide","onMonthChange","formatter","disabler"].forEach((function(e){"function"!=typeof t[e]&&(t[e]=s)})),["customDays","customMonths","customOverlayMonths"].forEach((function(e,n){var a=t[e],r=n?12:7;if(a){if(!Array.isArray(a)||a.length!==r||a.some((function(e){return"string"!=typeof e})))throw new Error('"'+e+'" must be an array with '+r+" strings.");t[n?n<2?"months":"overlayMonths":"days"]=a}})),f&&f>0&&f<7){var w=(t.customDays||r).slice(),D=w.splice(0,f);t.customDays=w.concat(D),t.startDay=+f,t.weekendIndices=[w.length-1,w.length]}else t.startDay=0,t.weekendIndices=[6,0];"string"!=typeof u&&delete t.overlayPlaceholder;"string"!=typeof h&&delete t.overlayButton;var q=t.defaultView;if(q&&"calendar"!==q&&"overlay"!==q)throw new Error('options.defaultView must either be "calendar" or "overlay".');return t.defaultView=q||"calendar",t}(t||{startDate:g(new Date),position:"bl",defaultView:"calendar"}),u=e;if("string"==typeof u)u="#"===u[0]?document.getElementById(u.slice(1)):document.querySelector(u);else{if("[object ShadowRoot]"===x(u))throw new Error("Using a shadow DOM as your selector is not supported.");for(var h,f=u.parentNode;!h;){var v=x(f);"[object HTMLDocument]"===v?h=!0:"[object ShadowRoot]"===v?(h=!0,n=f,l=f.host):f=f.parentNode}}if(!u)throw new Error("No selector / element found.");if(a.some((function(e){return e.el===u})))throw new Error("A datepicker already exists on that element.");var m=u===document.body,y=n?u.parentElement||n:m?document.body:u.parentElement,w=n?u.parentElement||l:y,D=document.createElement("div"),q=document.createElement("div");D.className="qs-datepicker-container qs-hidden",q.className="qs-datepicker";var M={shadowDom:n,customElement:l,positionedEl:w,el:u,parent:y,nonInput:"INPUT"!==u.nodeName,noPosition:m,position:!m&&d.position,startDate:d.startDate,dateSelected:d.dateSelected,disabledDates:d.disabledDates,minDate:d.minDate,maxDate:d.maxDate,noWeekends:!!d.noWeekends,weekendIndices:d.weekendIndices,calendarContainer:D,calendar:q,currentMonth:(d.startDate||d.dateSelected).getMonth(),currentMonthName:(d.months||i)[(d.startDate||d.dateSelected).getMonth()],currentYear:(d.startDate||d.dateSelected).getFullYear(),events:d.events||{},defaultView:d.defaultView,setDate:O,remove:R,setMin:N,setMax:_,show:P,hide:k,navigate:F,toggleOverlay:B,onSelect:d.onSelect,onShow:d.onShow,onHide:d.onHide,onMonthChange:d.onMonthChange,formatter:d.formatter,disabler:d.disabler,months:d.months||i,days:d.customDays||r,startDay:d.startDay,overlayMonths:d.overlayMonths||(d.months||i).map((function(e){return e.slice(0,3)})),overlayPlaceholder:d.overlayPlaceholder||"4-digit year",overlayButton:d.overlayButton||"Submit",disableYearOverlay:!!d.disableYearOverlay,disableMobile:!!d.disableMobile,isMobile:"ontouchstart"in window,alwaysShow:!!d.al
26323waysShow,id:d.id,showAllDates:!!d.showAllDates,respectDisabledReadOnly:!!d.respectDisabledReadOnly,first:d.first,second:d.second};if(d.sibling){var E=d.sibling,C=M,L=E.minDate||C.minDate,Y=E.maxDate||C.maxDate;C.sibling=E,E.sibling=C,E.minDate=L,E.maxDate=Y,C.minDate=L,C.maxDate=Y,E.originalMinDate=L,E.originalMaxDate=Y,C.originalMinDate=L,C.originalMaxDate=Y,E.getRange=A,C.getRange=A}d.dateSelected&&p(u,M);var j=getComputedStyle(w).position;m||j&&"static"!==j||(M.inlinePosition=!0,w.style.setProperty("position","relative"));var I=a.filter((function(e){return e.positionedEl===M.positionedEl}));I.some((function(e){return e.inlinePosition}))&&(M.inlinePosition=!0,I.forEach((function(e){e.inlinePosition=!0})));D.appendChild(q),y.appendChild(D),M.alwaysShow&&S(M);return M}(e,t);if(a.length||d(document),n.shadowDom&&(a.some((function(e){return e.shadowDom===n.shadowDom}))||d(n.shadowDom)),a.push(n),n.second){var l=n.sibling;y({instance:n,deselect:!n.dateSelected}),y({instance:l,deselect:!l.dateSelected}),u(l)}return u(n,n.startDate||n.dateSelected),n.alwaysShow&&D(n),n}}]).default}));
26324
26325/***/ }),
26326/* 4 */
26327/***/ (function(module, exports, __webpack_require__) {
26328
26329var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Buttons for DataTables 1.7.1
26330 * ©2016-2021 SpryMedia Ltd - datatables.net/license
26331 */
26332
26333(function( factory ){
26334	if ( true ) {
26335		// AMD
26336		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {
26337			return factory( $, window, document );
26338		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
26339				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
26340	}
26341	else {}
26342}(function( $, window, document, undefined ) {
26343'use strict';
26344var DataTable = $.fn.dataTable;
26345
26346
26347// Used for namespacing events added to the document by each instance, so they
26348// can be removed on destroy
26349var _instCounter = 0;
26350
26351// Button namespacing counter for namespacing events on individual buttons
26352var _buttonCounter = 0;
26353
26354var _dtButtons = DataTable.ext.buttons;
26355
26356// Allow for jQuery slim
26357function _fadeIn(el, duration, fn) {
26358	if ($.fn.animate) {
26359		el
26360			.stop()
26361			.fadeIn( duration, fn );
26362	}
26363	else {
26364		el.css('display', 'block');
26365
26366		if (fn) {
26367			fn.call(el);
26368		}
26369	}
26370}
26371
26372function _fadeOut(el, duration, fn) {
26373	if ($.fn.animate) {
26374		el
26375			.stop()
26376			.fadeOut( duration, fn );
26377	}
26378	else {
26379		el.css('display', 'none');
26380		
26381		if (fn) {
26382			fn.call(el);
26383		}
26384	}
26385}
26386
26387/**
26388 * [Buttons description]
26389 * @param {[type]}
26390 * @param {[type]}
26391 */
26392var Buttons = function( dt, config )
26393{
26394	// If not created with a `new` keyword then we return a wrapper function that
26395	// will take the settings object for a DT. This allows easy use of new instances
26396	// with the `layout` option - e.g. `topLeft: $.fn.dataTable.Buttons( ... )`.
26397	if ( !(this instanceof Buttons) ) {
26398		return function (settings) {
26399			return new Buttons( settings, dt ).container();
26400		};
26401	}
26402
26403	// If there is no config set it to an empty object
26404	if ( typeof( config ) === 'undefined' ) {
26405		config = {};	
26406	}
26407	
26408	// Allow a boolean true for defaults
26409	if ( config === true ) {
26410		config = {};
26411	}
26412
26413	// For easy configuration of buttons an array can be given
26414	if ( Array.isArray( config ) ) {
26415		config = { buttons: config };
26416	}
26417
26418	this.c = $.extend( true, {}, Buttons.defaults, config );
26419
26420	// Don't want a deep copy for the buttons
26421	if ( config.buttons ) {
26422		this.c.buttons = config.buttons;
26423	}
26424
26425	this.s = {
26426		dt: new DataTable.Api( dt ),
26427		buttons: [],
26428		listenKeys: '',
26429		namespace: 'dtb'+(_instCounter++)
26430	};
26431
26432	this.dom = {
26433		container: $('<'+this.c.dom.container.tag+'/>')
26434			.addClass( this.c.dom.container.className )
26435	};
26436
26437	this._constructor();
26438};
26439
26440
26441$.extend( Buttons.prototype, {
26442	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
26443	 * Public methods
26444	 */
26445
26446	/**
26447	 * Get the action of a button
26448	 * @param  {int|string} Button index
26449	 * @return {function}
26450	 *//**
26451	 * Set the action of a button
26452	 * @param  {node} node Button element
26453	 * @param  {function} action Function to set
26454	 * @return {Buttons} Self for chaining
26455	 */
26456	action: function ( node, action )
26457	{
26458		var button = this._nodeToButton( node );
26459
26460		if ( action === undefined ) {
26461			return button.conf.action;
26462		}
26463
26464		button.conf.action = action;
26465
26466		return this;
26467	},
26468
26469	/**
26470	 * Add an active class to the button to make to look active or get current
26471	 * active state.
26472	 * @param  {node} node Button element
26473	 * @param  {boolean} [flag] Enable / disable flag
26474	 * @return {Buttons} Self for chaining or boolean for getter
26475	 */
26476	active: function ( node, flag ) {
26477		var button = this._nodeToButton( node );
26478		var klass = this.c.dom.button.active;
26479		var jqNode = $(button.node);
26480
26481		if ( flag === undefined ) {
26482			return jqNode.hasClass( klass );
26483		}
26484
26485		jqNode.toggleClass( klass, flag === undefined ? true : flag );
26486
26487		return this;
26488	},
26489
26490	/**
26491	 * Add a new button
26492	 * @param {object} config Button configuration object, base string name or function
26493	 * @param {int|string} [idx] Button index for where to insert the button
26494	 * @return {Buttons} Self for chaining
26495	 */
26496	add: function ( config, idx )
26497	{
26498		var buttons = this.s.buttons;
26499
26500		if ( typeof idx === 'string' ) {
26501			var split = idx.split('-');
26502			var base = this.s;
26503
26504			for ( var i=0, ien=split.length-1 ; i<ien ; i++ ) {
26505				base = base.buttons[ split[i]*1 ];
26506			}
26507
26508			buttons = base.buttons;
26509			idx = split[ split.length-1 ]*1;
26510		}
26511
26512		this._expandButton( buttons, config, base !== undefined, idx );
26513		this._draw();
26514
26515		return this;
26516	},
26517
26518	/**
26519	 * Get the container node for the buttons
26520	 * @return {jQuery} Buttons node
26521	 */
26522	container: function ()
26523	{
26524		return this.dom.container;
26525	},
26526
26527	/**
26528	 * Disable a button
26529	 * @param  {node} node Button node
26530	 * @return {Buttons} Self for chaining
26531	 */
26532	disable: function ( node ) {
26533		var button = this._nodeToButton( node );
26534
26535		$(button.node)
26536			.addClass( this.c.dom.button.disabled )
26537			.attr('disabled', true);
26538
26539		return this;
26540	},
26541
26542	/**
26543	 * Destroy the instance, cleaning up event handlers and removing DOM
26544	 * elements
26545	 * @return {Buttons} Self for chaining
26546	 */
26547	destroy: function ()
26548	{
26549		// Key event listener
26550		$('body').off( 'keyup.'+this.s.namespace );
26551
26552		// Individual button destroy (so they can remove their own events if
26553		// needed). Take a copy as the array is modified by `remove`
26554		var buttons = this.s.buttons.slice();
26555		var i, ien;
26556		
26557		for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
26558			this.remove( buttons[i].node );
26559		}
26560
26561		// Container
26562		this.dom.container.remove();
26563
26564		// Remove from the settings object collection
26565		var buttonInsts = this.s.dt.settings()[0];
26566
26567		for ( i=0, ien=buttonInsts.length ; i<ien ; i++ ) {
26568			if ( buttonInsts.inst === this ) {
26569				buttonInsts.splice( i, 1 );
26570				break;
26571			}
26572		}
26573
26574		return this;
26575	},
26576
26577	/**
26578	 * Enable / disable a button
26579	 * @param  {node} node Button node
26580	 * @param  {boolean} [flag=true] Enable / disable flag
26581	 * @return {Buttons} Self for chaining
26582	 */
26583	enable: function ( node, flag )
26584	{
26585		if ( flag === false ) {
26586			return this.disable( node );
26587		}
26588
26589		var button = this._nodeToButton( node );
26590		$(button.node)
26591			.removeClass( this.c.dom.button.disabled )
26592			.removeAttr('disabled');
26593
26594		return this;
26595	},
26596
26597	/**
26598	 * Get the instance name for the button set selector
26599	 * @return {string} Instance name
26600	 */
26601	name: function ()
26602	{
26603		return this.c.name;
26604	},
26605
26606	/**
26607	 * Get a button's node of the buttons container if no button is given
26608	 * @param  {node} [node] Button node
26609	 * @return {jQuery} Button element, or container
26610	 */
26611	node: function ( node )
26612	{
26613		if ( ! node ) {
26614			return this.dom.container;
26615		}
26616
26617		var button = this._nodeToButton( node );
26618		return $(button.node);
26619	},
26620
26621	/**
26622	 * Set / get a processing class on the selected button
26623	 * @param {element} node Triggering button node
26624	 * @param  {boolean} flag true to add, false to remove, undefined to get
26625	 * @return {boolean|Buttons} Getter value or this if a setter.
26626	 */
26627	processing: function ( node, flag )
26628	{
26629		var dt = this.s.dt;
26630		var button = this._nodeToButton( node );
26631
26632		if ( flag === undefined ) {
26633			return $(button.node).hasClass( 'processing' );
26634		}
26635
26636		$(button.node).toggleClass( 'processing', flag );
26637
26638		$(dt.table().node()).triggerHandler( 'buttons-processing.dt', [
26639			flag, dt.button( node ), dt, $(node), button.conf
26640		] );
26641
26642		return this;
26643	},
26644
26645	/**
26646	 * Remove a button.
26647	 * @param  {node} node Button node
26648	 * @return {Buttons} Self for chaining
26649	 */
26650	remove: function ( node )
26651	{
26652		var button = this._nodeToButton( node );
26653		var host = this._nodeToHost( node );
26654		var dt = this.s.dt;
26655
26656		// Remove any child buttons first
26657		if ( button.buttons.length ) {
26658			for ( var i=button.buttons.length-1 ; i>=0 ; i-- ) {
26659				this.remove( button.buttons[i].node );
26660			}
26661		}
26662
26663		// Allow the button to remove event handlers, etc
26664		if ( button.conf.destroy ) {
26665			button.conf.destroy.call( dt.button(node), dt, $(node), button.conf );
26666		}
26667
26668		this._removeKey( button.conf );
26669
26670		$(button.node).remove();
26671
26672		var idx = $.inArray( button, host );
26673		host.splice( idx, 1 );
26674
26675		return this;
26676	},
26677
26678	/**
26679	 * Get the text for a button
26680	 * @param  {int|string} node Button index
26681	 * @return {string} Button text
26682	 *//**
26683	 * Set the text for a button
26684	 * @param  {int|string|function} node Button index
26685	 * @param  {string} label Text
26686	 * @return {Buttons} Self for chaining
26687	 */
26688	text: function ( node, label )
26689	{
26690		var button = this._nodeToButton( node );
26691		var buttonLiner = this.c.dom.collection.buttonLiner;
26692		var linerTag = button.inCollection && buttonLiner && buttonLiner.tag ?
26693			buttonLiner.tag :
26694			this.c.dom.buttonLiner.tag;
26695		var dt = this.s.dt;
26696		var jqNode = $(button.node);
26697		var text = function ( opt ) {
26698			return typeof opt === 'function' ?
26699				opt( dt, jqNode, button.conf ) :
26700				opt;
26701		};
26702
26703		if ( label === undefined ) {
26704			return text( button.conf.text );
26705		}
26706
26707		button.conf.text = label;
26708
26709		if ( linerTag ) {
26710			jqNode.children( linerTag ).html( text(label) );
26711		}
26712		else {
26713			jqNode.html( text(label) );
26714		}
26715
26716		return this;
26717	},
26718
26719
26720	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
26721	 * Constructor
26722	 */
26723
26724	/**
26725	 * Buttons constructor
26726	 * @private
26727	 */
26728	_constructor: function ()
26729	{
26730		var that = this;
26731		var dt = this.s.dt;
26732		var dtSettings = dt.settings()[0];
26733		var buttons =  this.c.buttons;
26734
26735		if ( ! dtSettings._buttons ) {
26736			dtSettings._buttons = [];
26737		}
26738
26739		dtSettings._buttons.push( {
26740			inst: this,
26741			name: this.c.name
26742		} );
26743
26744		for ( var i=0, ien=buttons.length ; i<ien ; i++ ) {
26745			this.add( buttons[i] );
26746		}
26747
26748		dt.on( 'destroy', function ( e, settings ) {
26749			if ( settings === dtSettings ) {
26750				that.destroy();
26751			}
26752		} );
26753
26754		// Global key event binding to listen for button keys
26755		$('body').on( 'keyup.'+this.s.namespace, function ( e ) {
26756			if ( ! document.activeElement || document.activeElement === document.body ) {
26757				// SUse a string of characters for fast lookup of if we need to
26758				// handle this
26759				var character = String.fromCharCode(e.keyCode).toLowerCase();
26760
26761				if ( that.s.listenKeys.toLowerCase().indexOf( character ) !== -1 ) {
26762					that._keypress( character, e );
26763				}
26764			}
26765		} );
26766	},
26767
26768
26769	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
26770	 * Private methods
26771	 */
26772
26773	/**
26774	 * Add a new button to the key press listener
26775	 * @param {object} conf Resolved button configuration object
26776	 * @private
26777	 */
26778	_addKey: function ( conf )
26779	{
26780		if ( conf.key ) {
26781			this.s.listenKeys += $.isPlainObject( conf.key ) ?
26782				conf.key.key :
26783				conf.key;
26784		}
26785	},
26786
26787	/**
26788	 * Insert the buttons into the container. Call without parameters!
26789	 * @param  {node} [container] Recursive only - Insert point
26790	 * @param  {array} [buttons] Recursive only - Buttons array
26791	 * @private
26792	 */
26793	_draw: function ( container, buttons )
26794	{
26795		if ( ! container ) {
26796			container = this.dom.container;
26797			buttons = this.s.buttons;
26798		}
26799
26800		container.children().detach();
26801
26802		for ( var i=0, ien=buttons.length ; i<ien ; i++ ) {
26803			container.append( buttons[i].inserter );
26804			container.append( ' ' );
26805
26806			if ( buttons[i].buttons && buttons[i].buttons.length ) {
26807				this._draw( buttons[i].collection, buttons[i].buttons );
26808			}
26809		}
26810	},
26811
26812	/**
26813	 * Create buttons from an array of buttons
26814	 * @param  {array} attachTo Buttons array to attach to
26815	 * @param  {object} button Button definition
26816	 * @param  {boolean} inCollection true if the button is in a collection
26817	 * @private
26818	 */
26819	_expandButton: function ( attachTo, button, inCollection, attachPoint )
26820	{
26821		var dt = this.s.dt;
26822		var buttonCounter = 0;
26823		var buttons = ! Array.isArray( button ) ?
26824			[ button ] :
26825			button;
26826
26827		for ( var i=0, ien=buttons.length ; i<ien ; i++ ) {
26828			var conf = this._resolveExtends( buttons[i] );
26829
26830			if ( ! conf ) {
26831				continue;
26832			}
26833
26834			// If the configuration is an array, then expand the buttons at this
26835			// point
26836			if ( Array.isArray( conf ) ) {
26837				this._expandButton( attachTo, conf, inCollection, attachPoint );
26838				continue;
26839			}
26840
26841			var built = this._buildButton( conf, inCollection );
26842			if ( ! built ) {
26843				continue;
26844			}
26845
26846			if ( attachPoint !== undefined && attachPoint !== null ) {
26847				attachTo.splice( attachPoint, 0, built );
26848				attachPoint++;
26849			}
26850			else {
26851				attachTo.push( built );
26852			}
26853
26854			if ( built.conf.buttons ) {
26855				built.collection = $('<'+this.c.dom.collection.tag+'/>');
26856
26857				built.conf._collection = built.collection;
26858
26859				this._expandButton( built.buttons, built.conf.buttons, true, attachPoint );
26860			}
26861
26862			// init call is made here, rather than buildButton as it needs to
26863			// be selectable, and for that it needs to be in the buttons array
26864			if ( conf.init ) {
26865				conf.init.call( dt.button( built.node ), dt, $(built.node), conf );
26866			}
26867
26868			buttonCounter++;
26869		}
26870	},
26871
26872	/**
26873	 * Create an individual button
26874	 * @param  {object} config            Resolved button configuration
26875	 * @param  {boolean} inCollection `true` if a collection button
26876	 * @return {jQuery} Created button node (jQuery)
26877	 * @private
26878	 */
26879	_buildButton: function ( config, inCollection )
26880	{
26881		var buttonDom = this.c.dom.button;
26882		var linerDom = this.c.dom.buttonLiner;
26883		var collectionDom = this.c.dom.collection;
26884		var dt = this.s.dt;
26885		var text = function ( opt ) {
26886			return typeof opt === 'function' ?
26887				opt( dt, button, config ) :
26888				opt;
26889		};
26890
26891		if ( inCollection && collectionDom.button ) {
26892			buttonDom = collectionDom.button;
26893		}
26894
26895		if ( inCollection && collectionDom.buttonLiner ) {
26896			linerDom = collectionDom.buttonLiner;
26897		}
26898
26899		// Make sure that the button is available based on whatever requirements
26900		// it has. For example, PDF button require pdfmake
26901		if ( config.available && ! config.available( dt, config ) ) {
26902			return false;
26903		}
26904
26905		var action = function ( e, dt, button, config ) {
26906			config.action.call( dt.button( button ), e, dt, button, config );
26907
26908			$(dt.table().node()).triggerHandler( 'buttons-action.dt', [
26909				dt.button( button ), dt, button, config 
26910			] );
26911		};
26912
26913		var tag = config.tag || buttonDom.tag;
26914		var clickBlurs = config.clickBlurs === undefined ? true : config.clickBlurs
26915		var button = $('<'+tag+'/>')
26916			.addClass( buttonDom.className )
26917			.attr( 'tabindex', this.s.dt.settings()[0].iTabIndex )
26918			.attr( 'aria-controls', this.s.dt.table().node().id )
26919			.on( 'click.dtb', function (e) {
26920				e.preventDefault();
26921
26922				if ( ! button.hasClass( buttonDom.disabled ) && config.action ) {
26923					action( e, dt, button, config );
26924				}
26925				if( clickBlurs ) {
26926					button.trigger('blur');
26927				}
26928			} )
26929			.on( 'keyup.dtb', function (e) {
26930				if ( e.keyCode === 13 ) {
26931					if ( ! button.hasClass( buttonDom.disabled ) && config.action ) {
26932						action( e, dt, button, config );
26933					}
26934				}
26935			} );
26936
26937		// Make `a` tags act like a link
26938		if ( tag.toLowerCase() === 'a' ) {
26939			button.attr( 'href', '#' );
26940		}
26941
26942		// Button tags should have `type=button` so they don't have any default behaviour
26943		if ( tag.toLowerCase() === 'button' ) {
26944			button.attr( 'type', 'button' );
26945		}
26946
26947		if ( linerDom.tag ) {
26948			var liner = $('<'+linerDom.tag+'/>')
26949				.html( text( config.text ) )
26950				.addClass( linerDom.className );
26951
26952			if ( linerDom.tag.toLowerCase() === 'a' ) {
26953				liner.attr( 'href', '#' );
26954			}
26955
26956			button.append( liner );
26957		}
26958		else {
26959			button.html( text( config.text ) );
26960		}
26961
26962		if ( config.enabled === false ) {
26963			button.addClass( buttonDom.disabled );
26964		}
26965
26966		if ( config.className ) {
26967			button.addClass( config.className );
26968		}
26969
26970		if ( config.titleAttr ) {
26971			button.attr( 'title', text( config.titleAttr ) );
26972		}
26973
26974		if ( config.attr ) {
26975			button.attr( config.attr );
26976		}
26977
26978		if ( ! config.namespace ) {
26979			config.namespace = '.dt-button-'+(_buttonCounter++);
26980		}
26981
26982		var buttonContainer = this.c.dom.buttonContainer;
26983		var inserter;
26984		if ( buttonContainer && buttonContainer.tag ) {
26985			inserter = $('<'+buttonContainer.tag+'/>')
26986				.addClass( buttonContainer.className )
26987				.append( button );
26988		}
26989		else {
26990			inserter = button;
26991		}
26992
26993		this._addKey( config );
26994
26995		// Style integration callback for DOM manipulation
26996		// Note that this is _not_ documented. It is currently
26997		// for style integration only
26998		if( this.c.buttonCreated ) {
26999			inserter = this.c.buttonCreated( config, inserter );
27000		}
27001
27002		return {
27003			conf:         config,
27004			node:         button.get(0),
27005			inserter:     inserter,
27006			buttons:      [],
27007			inCollection: inCollection,
27008			collection:   null
27009		};
27010	},
27011
27012	/**
27013	 * Get the button object from a node (recursive)
27014	 * @param  {node} node Button node
27015	 * @param  {array} [buttons] Button array, uses base if not defined
27016	 * @return {object} Button object
27017	 * @private
27018	 */
27019	_nodeToButton: function ( node, buttons )
27020	{
27021		if ( ! buttons ) {
27022			buttons = this.s.buttons;
27023		}
27024
27025		for ( var i=0, ien=buttons.length ; i<ien ; i++ ) {
27026			if ( buttons[i].node === node ) {
27027				return buttons[i];
27028			}
27029
27030			if ( buttons[i].buttons.length ) {
27031				var ret = this._nodeToButton( node, buttons[i].buttons );
27032
27033				if ( ret ) {
27034					return ret;
27035				}
27036			}
27037		}
27038	},
27039
27040	/**
27041	 * Get container array for a button from a button node (recursive)
27042	 * @param  {node} node Button node
27043	 * @param  {array} [buttons] Button array, uses base if not defined
27044	 * @return {array} Button's host array
27045	 * @private
27046	 */
27047	_nodeToHost: function ( node, buttons )
27048	{
27049		if ( ! buttons ) {
27050			buttons = this.s.buttons;
27051		}
27052
27053		for ( var i=0, ien=buttons.length ; i<ien ; i++ ) {
27054			if ( buttons[i].node === node ) {
27055				return buttons;
27056			}
27057
27058			if ( buttons[i].buttons.length ) {
27059				var ret = this._nodeToHost( node, buttons[i].buttons );
27060
27061				if ( ret ) {
27062					return ret;
27063				}
27064			}
27065		}
27066	},
27067
27068	/**
27069	 * Handle a key press - determine if any button's key configured matches
27070	 * what was typed and trigger the action if so.
27071	 * @param  {string} character The character pressed
27072	 * @param  {object} e Key event that triggered this call
27073	 * @private
27074	 */
27075	_keypress: function ( character, e )
27076	{
27077		// Check if this button press already activated on another instance of Buttons
27078		if ( e._buttonsHandled ) {
27079			return;
27080		}
27081
27082		var run = function ( conf, node ) {
27083			if ( ! conf.key ) {
27084				return;
27085			}
27086
27087			if ( conf.key === character ) {
27088				e._buttonsHandled = true;
27089				$(node).click();
27090			}
27091			else if ( $.isPlainObject( conf.key ) ) {
27092				if ( conf.key.key !== character ) {
27093					return;
27094				}
27095
27096				if ( conf.key.shiftKey && ! e.shiftKey ) {
27097					return;
27098				}
27099
27100				if ( conf.key.altKey && ! e.altKey ) {
27101					return;
27102				}
27103
27104				if ( conf.key.ctrlKey && ! e.ctrlKey ) {
27105					return;
27106				}
27107
27108				if ( conf.key.metaKey && ! e.metaKey ) {
27109					return;
27110				}
27111
27112				// Made it this far - it is good
27113				e._buttonsHandled = true;
27114				$(node).click();
27115			}
27116		};
27117
27118		var recurse = function ( a ) {
27119			for ( var i=0, ien=a.length ; i<ien ; i++ ) {
27120				run( a[i].conf, a[i].node );
27121
27122				if ( a[i].buttons.length ) {
27123					recurse( a[i].buttons );
27124				}
27125			}
27126		};
27127
27128		recurse( this.s.buttons );
27129	},
27130
27131	/**
27132	 * Remove a key from the key listener for this instance (to be used when a
27133	 * button is removed)
27134	 * @param  {object} conf Button configuration
27135	 * @private
27136	 */
27137	_removeKey: function ( conf )
27138	{
27139		if ( conf.key ) {
27140			var character = $.isPlainObject( conf.key ) ?
27141				conf.key.key :
27142				conf.key;
27143
27144			// Remove only one character, as multiple buttons could have the
27145			// same listening key
27146			var a = this.s.listenKeys.split('');
27147			var idx = $.inArray( character, a );
27148			a.splice( idx, 1 );
27149			this.s.listenKeys = a.join('');
27150		}
27151	},
27152
27153	/**
27154	 * Resolve a button configuration
27155	 * @param  {string|function|object} conf Button config to resolve
27156	 * @return {object} Button configuration
27157	 * @private
27158	 */
27159	_resolveExtends: function ( conf )
27160	{
27161		var dt = this.s.dt;
27162		var i, ien;
27163		var toConfObject = function ( base ) {
27164			var loop = 0;
27165
27166			// Loop until we have resolved to a button configuration, or an
27167			// array of button configurations (which will be iterated
27168			// separately)
27169			while ( ! $.isPlainObject(base) && ! Array.isArray(base) ) {
27170				if ( base === undefined ) {
27171					return;
27172				}
27173
27174				if ( typeof base === 'function' ) {
27175					base = base( dt, conf );
27176
27177					if ( ! base ) {
27178						return false;
27179					}
27180				}
27181				else if ( typeof base === 'string' ) {
27182					if ( ! _dtButtons[ base ] ) {
27183						throw 'Unknown button type: '+base;
27184					}
27185
27186					base = _dtButtons[ base ];
27187				}
27188
27189				loop++;
27190				if ( loop > 30 ) {
27191					// Protect against misconfiguration killing the browser
27192					throw 'Buttons: Too many iterations';
27193				}
27194			}
27195
27196			return Array.isArray( base ) ?
27197				base :
27198				$.extend( {}, base );
27199		};
27200
27201		conf = toConfObject( conf );
27202
27203		while ( conf && conf.extend ) {
27204			// Use `toConfObject` in case the button definition being extended
27205			// is itself a string or a function
27206			if ( ! _dtButtons[ conf.extend ] ) {
27207				throw 'Cannot extend unknown button type: '+conf.extend;
27208			}
27209
27210			var objArray = toConfObject( _dtButtons[ conf.extend ] );
27211			if ( Array.isArray( objArray ) ) {
27212				return objArray;
27213			}
27214			else if ( ! objArray ) {
27215				// This is a little brutal as it might be possible to have a
27216				// valid button without the extend, but if there is no extend
27217				// then the host button would be acting in an undefined state
27218				return false;
27219			}
27220
27221			// Stash the current class name
27222			var originalClassName = objArray.className;
27223
27224			conf = $.extend( {}, objArray, conf );
27225
27226			// The extend will have overwritten the original class name if the
27227			// `conf` object also assigned a class, but we want to concatenate
27228			// them so they are list that is combined from all extended buttons
27229			if ( originalClassName && conf.className !== originalClassName ) {
27230				conf.className = originalClassName+' '+conf.className;
27231			}
27232
27233			// Buttons to be added to a collection  -gives the ability to define
27234			// if buttons should be added to the start or end of a collection
27235			var postfixButtons = conf.postfixButtons;
27236			if ( postfixButtons ) {
27237				if ( ! conf.buttons ) {
27238					conf.buttons = [];
27239				}
27240
27241				for ( i=0, ien=postfixButtons.length ; i<ien ; i++ ) {
27242					conf.buttons.push( postfixButtons[i] );
27243				}
27244
27245				conf.postfixButtons = null;
27246			}
27247
27248			var prefixButtons = conf.prefixButtons;
27249			if ( prefixButtons ) {
27250				if ( ! conf.buttons ) {
27251					conf.buttons = [];
27252				}
27253
27254				for ( i=0, ien=prefixButtons.length ; i<ien ; i++ ) {
27255					conf.buttons.splice( i, 0, prefixButtons[i] );
27256				}
27257
27258				conf.prefixButtons = null;
27259			}
27260
27261			// Although we want the `conf` object to overwrite almost all of
27262			// the properties of the object being extended, the `extend`
27263			// property should come from the object being extended
27264			conf.extend = objArray.extend;
27265		}
27266
27267		return conf;
27268	},
27269
27270	/**
27271	 * Display (and replace if there is an existing one) a popover attached to a button
27272	 * @param {string|node} content Content to show
27273	 * @param {DataTable.Api} hostButton DT API instance of the button
27274	 * @param {object} inOpts Options (see object below for all options)
27275	 */
27276	_popover: function ( content, hostButton, inOpts ) {
27277		var dt = hostButton;
27278		var buttonsSettings = this.c;
27279		var options = $.extend( {
27280			align: 'button-left', // button-right, dt-container
27281			autoClose: false,
27282			background: true,
27283			backgroundClassName: 'dt-button-background',
27284			contentClassName: buttonsSettings.dom.collection.className,
27285			collectionLayout: '',
27286			collectionTitle: '',
27287			dropup: false,
27288			fade: 400,
27289			rightAlignClassName: 'dt-button-right',
27290			tag: buttonsSettings.dom.collection.tag
27291		}, inOpts );
27292		var hostNode = hostButton.node();
27293
27294		var close = function () {
27295			_fadeOut(
27296				$('.dt-button-collection'),
27297				options.fade,
27298				function () {
27299					$(this).detach();
27300				}
27301			);
27302
27303			$(dt.buttons( '[aria-haspopup="true"][aria-expanded="true"]' ).nodes())
27304				.attr('aria-expanded', 'false');
27305
27306			$('div.dt-button-background').off( 'click.dtb-collection' );
27307			Buttons.background( false, options.backgroundClassName, options.fade, hostNode );
27308
27309			$('body').off( '.dtb-collection' );
27310			dt.off( 'buttons-action.b-internal' );
27311		};
27312
27313		if (content === false) {
27314			close();
27315		}
27316
27317		var existingExpanded = $(dt.buttons( '[aria-haspopup="true"][aria-expanded="true"]' ).nodes());
27318		if ( existingExpanded.length ) {
27319			hostNode = existingExpanded.eq(0);
27320
27321			close();
27322		}
27323
27324		var display = $('<div/>')
27325			.addClass('dt-button-collection')
27326			.addClass(options.collectionLayout)
27327			.css('display', 'none');
27328
27329		content = $(content)
27330			.addClass(options.contentClassName)
27331			.attr('role', 'menu')
27332			.appendTo(display);
27333
27334		hostNode.attr( 'aria-expanded', 'true' );
27335
27336		if ( hostNode.parents('body')[0] !== document.body ) {
27337			hostNode = document.body.lastChild;
27338		}
27339
27340		if ( options.collectionTitle ) {
27341			display.prepend('<div class="dt-button-collection-title">'+options.collectionTitle+'</div>');
27342		}
27343
27344		_fadeIn( display.insertAfter( hostNode ), options.fade );
27345
27346		var tableContainer = $( hostButton.table().container() );
27347		var position = display.css( 'position' );
27348
27349		if ( options.align === 'dt-container' ) {
27350			hostNode = hostNode.parent();
27351			display.css('width', tableContainer.width());
27352		}
27353
27354		// Align the popover relative to the DataTables container
27355		// Useful for wide popovers such as SearchPanes
27356		if (position === 'absolute') {
27357			// Align relative to the host button
27358			var hostPosition = hostNode.position();
27359			var buttonPosition = $(hostButton.node()).position();
27360
27361			display.css( {
27362				top: buttonPosition.top + hostNode.outerHeight(),
27363				left: hostPosition.left
27364			} );
27365
27366			// calculate overflow when positioned beneath
27367			var collectionHeight = display.outerHeight();
27368			var tableBottom = tableContainer.offset().top + tableContainer.height();
27369			var listBottom = buttonPosition.top + hostNode.outerHeight() + collectionHeight;
27370			var bottomOverflow = listBottom - tableBottom;
27371
27372			// calculate overflow when positioned above
27373			var listTop = buttonPosition.top - collectionHeight;
27374			var tableTop = tableContainer.offset().top;
27375			var topOverflow = tableTop - listTop;
27376
27377			// if bottom overflow is larger, move to the top because it fits better, or if dropup is requested
27378			var moveTop = buttonPosition.top - collectionHeight - 5;
27379			if ( (bottomOverflow > topOverflow || options.dropup) && -moveTop < tableTop ) {
27380				display.css( 'top', moveTop);
27381			}
27382
27383			// Get the size of the container (left and width - and thus also right)
27384			var tableLeft = tableContainer.offset().left;
27385			var tableWidth = tableContainer.width();
27386			var tableRight = tableLeft + tableWidth;
27387
27388			// Get the size of the popover (left and width - and ...)
27389			var popoverLeft = display.offset().left;
27390			var popoverWidth = display.width();
27391			var popoverRight = popoverLeft + popoverWidth;
27392
27393			// Get the size of the host buttons (left and width - and ...)
27394			var buttonsLeft = hostNode.offset().left;
27395			var buttonsWidth = hostNode.outerWidth()
27396			var buttonsRight = buttonsLeft + buttonsWidth;
27397
27398			if (
27399				display.hasClass( options.rightAlignClassName ) ||
27400				display.hasClass( options.leftAlignClassName ) ||
27401				options.align === 'dt-container'
27402			){
27403				// You've then got all the numbers you need to do some calculations and if statements,
27404				//  so we can do some quick JS maths and apply it only once
27405				// If it has the right align class OR the buttons are right aligned OR the button container is floated right,
27406				//  then calculate left position for the popover to align the popover to the right hand
27407				//  side of the button - check to see if the left of the popover is inside the table container.
27408				// If not, move the popover so it is, but not more than it means that the popover is to the right of the table container
27409				var popoverShuffle = 0;
27410				if ( display.hasClass( options.rightAlignClassName )) {
27411					popoverShuffle = buttonsRight - popoverRight;
27412					if(tableLeft > (popoverLeft + popoverShuffle)){
27413						var leftGap = tableLeft - (popoverLeft + popoverShuffle);
27414						var rightGap = tableRight - (popoverRight + popoverShuffle);
27415		
27416						if(leftGap > rightGap){
27417							popoverShuffle += rightGap; 
27418						}
27419						else {
27420							popoverShuffle += leftGap;
27421						}
27422					}
27423				}
27424				// else attempt to left align the popover to the button. Similar to above, if the popover's right goes past the table container's right,
27425				//  then move it back, but not so much that it goes past the left of the table container
27426				else {
27427					popoverShuffle = tableLeft - popoverLeft;
27428	
27429					if(tableRight < (popoverRight + popoverShuffle)){
27430						var leftGap = tableLeft - (popoverLeft + popoverShuffle);
27431						var rightGap = tableRight - (popoverRight + popoverShuffle);
27432	
27433						if(leftGap > rightGap ){
27434							popoverShuffle += rightGap;
27435						}
27436						else {
27437							popoverShuffle += leftGap;
27438						}
27439	
27440					}
27441				}
27442	
27443				display.css('left', display.position().left + popoverShuffle);
27444			}
27445			else {
27446				var top = hostNode.offset().top
27447				var popoverShuffle = 0;
27448
27449				popoverShuffle = options.align === 'button-right'
27450					? buttonsRight - popoverRight
27451					: buttonsLeft - popoverLeft;
27452
27453				display.css('left', display.position().left + popoverShuffle);
27454			}
27455			
27456			
27457		}
27458		else {
27459			// Fix position - centre on screen
27460			var top = display.height() / 2;
27461			if ( top > $(window).height() / 2 ) {
27462				top = $(window).height() / 2;
27463			}
27464
27465			display.css( 'marginTop', top*-1 );
27466		}
27467
27468		if ( options.background ) {
27469			Buttons.background( true, options.backgroundClassName, options.fade, hostNode );
27470		}
27471
27472		// This is bonkers, but if we don't have a click listener on the
27473		// background element, iOS Safari will ignore the body click
27474		// listener below. An empty function here is all that is
27475		// required to make it work...
27476		$('div.dt-button-background').on( 'click.dtb-collection', function () {} );
27477
27478		$('body')
27479			.on( 'click.dtb-collection', function (e) {
27480				// andSelf is deprecated in jQ1.8, but we want 1.7 compat
27481				var back = $.fn.addBack ? 'addBack' : 'andSelf';
27482				var parent = $(e.target).parent()[0];
27483
27484				if (( ! $(e.target).parents()[back]().filter( content ).length  && !$(parent).hasClass('dt-buttons')) || $(e.target).hasClass('dt-button-background')) {
27485					close();
27486				}
27487			} )
27488			.on( 'keyup.dtb-collection', function (e) {
27489				if ( e.keyCode === 27 ) {
27490					close();
27491				}
27492			} );
27493
27494		if ( options.autoClose ) {
27495			setTimeout( function () {
27496				dt.on( 'buttons-action.b-internal', function (e, btn, dt, node) {
27497					if ( node[0] === hostNode[0] ) {
27498						return;
27499					}
27500					close();
27501				} );
27502			}, 0);
27503		}
27504
27505		$(display).trigger('buttons-popover.dt');
27506	}
27507} );
27508
27509
27510
27511/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
27512 * Statics
27513 */
27514
27515/**
27516 * Show / hide a background layer behind a collection
27517 * @param  {boolean} Flag to indicate if the background should be shown or
27518 *   hidden 
27519 * @param  {string} Class to assign to the background
27520 * @static
27521 */
27522Buttons.background = function ( show, className, fade, insertPoint ) {
27523	if ( fade === undefined ) {
27524		fade = 400;
27525	}
27526	if ( ! insertPoint ) {
27527		insertPoint = document.body;
27528	}
27529
27530	if ( show ) {
27531		_fadeIn(
27532			$('<div/>')
27533				.addClass( className )
27534				.css( 'display', 'none' )
27535				.insertAfter( insertPoint ),
27536			fade
27537		);
27538	}
27539	else {
27540		_fadeOut(
27541			$('div.'+className),
27542			fade,
27543			function () {
27544				$(this)
27545					.removeClass( className )
27546					.remove();
27547			}
27548		);
27549	}
27550};
27551
27552/**
27553 * Instance selector - select Buttons instances based on an instance selector
27554 * value from the buttons assigned to a DataTable. This is only useful if
27555 * multiple instances are attached to a DataTable.
27556 * @param  {string|int|array} Instance selector - see `instance-selector`
27557 *   documentation on the DataTables site
27558 * @param  {array} Button instance array that was attached to the DataTables
27559 *   settings object
27560 * @return {array} Buttons instances
27561 * @static
27562 */
27563Buttons.instanceSelector = function ( group, buttons )
27564{
27565	if ( group === undefined || group === null ) {
27566		return $.map( buttons, function ( v ) {
27567			return v.inst;
27568		} );
27569	}
27570
27571	var ret = [];
27572	var names = $.map( buttons, function ( v ) {
27573		return v.name;
27574	} );
27575
27576	// Flatten the group selector into an array of single options
27577	var process = function ( input ) {
27578		if ( Array.isArray( input ) ) {
27579			for ( var i=0, ien=input.length ; i<ien ; i++ ) {
27580				process( input[i] );
27581			}
27582			return;
27583		}
27584
27585		if ( typeof input === 'string' ) {
27586			if ( input.indexOf( ',' ) !== -1 ) {
27587				// String selector, list of names
27588				process( input.split(',') );
27589			}
27590			else {
27591				// String selector individual name
27592				var idx = $.inArray( input.trim(), names );
27593
27594				if ( idx !== -1 ) {
27595					ret.push( buttons[ idx ].inst );
27596				}
27597			}
27598		}
27599		else if ( typeof input === 'number' ) {
27600			// Index selector
27601			ret.push( buttons[ input ].inst );
27602		}
27603	};
27604	
27605	process( group );
27606
27607	return ret;
27608};
27609
27610/**
27611 * Button selector - select one or more buttons from a selector input so some
27612 * operation can be performed on them.
27613 * @param  {array} Button instances array that the selector should operate on
27614 * @param  {string|int|node|jQuery|array} Button selector - see
27615 *   `button-selector` documentation on the DataTables site
27616 * @return {array} Array of objects containing `inst` and `idx` properties of
27617 *   the selected buttons so you know which instance each button belongs to.
27618 * @static
27619 */
27620Buttons.buttonSelector = function ( insts, selector )
27621{
27622	var ret = [];
27623	var nodeBuilder = function ( a, buttons, baseIdx ) {
27624		var button;
27625		var idx;
27626
27627		for ( var i=0, ien=buttons.length ; i<ien ; i++ ) {
27628			button = buttons[i];
27629
27630			if ( button ) {
27631				idx = baseIdx !== undefined ?
27632					baseIdx+i :
27633					i+'';
27634
27635				a.push( {
27636					node: button.node,
27637					name: button.conf.name,
27638					idx:  idx
27639				} );
27640
27641				if ( button.buttons ) {
27642					nodeBuilder( a, button.buttons, idx+'-' );
27643				}
27644			}
27645		}
27646	};
27647
27648	var run = function ( selector, inst ) {
27649		var i, ien;
27650		var buttons = [];
27651		nodeBuilder( buttons, inst.s.buttons );
27652
27653		var nodes = $.map( buttons, function (v) {
27654			return v.node;
27655		} );
27656
27657		if ( Array.isArray( selector ) || selector instanceof $ ) {
27658			for ( i=0, ien=selector.length ; i<ien ; i++ ) {
27659				run( selector[i], inst );
27660			}
27661			return;
27662		}
27663
27664		if ( selector === null || selector === undefined || selector === '*' ) {
27665			// Select all
27666			for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
27667				ret.push( {
27668					inst: inst,
27669					node: buttons[i].node
27670				} );
27671			}
27672		}
27673		else if ( typeof selector === 'number' ) {
27674			// Main button index selector
27675			ret.push( {
27676				inst: inst,
27677				node: inst.s.buttons[ selector ].node
27678			} );
27679		}
27680		else if ( typeof selector === 'string' ) {
27681			if ( selector.indexOf( ',' ) !== -1 ) {
27682				// Split
27683				var a = selector.split(',');
27684
27685				for ( i=0, ien=a.length ; i<ien ; i++ ) {
27686					run( a[i].trim(), inst );
27687				}
27688			}
27689			else if ( selector.match( /^\d+(\-\d+)*$/ ) ) {
27690				// Sub-button index selector
27691				var indexes = $.map( buttons, function (v) {
27692					return v.idx;
27693				} );
27694
27695				ret.push( {
27696					inst: inst,
27697					node: buttons[ $.inArray( selector, indexes ) ].node
27698				} );
27699			}
27700			else if ( selector.indexOf( ':name' ) !== -1 ) {
27701				// Button name selector
27702				var name = selector.replace( ':name', '' );
27703
27704				for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
27705					if ( buttons[i].name === name ) {
27706						ret.push( {
27707							inst: inst,
27708							node: buttons[i].node
27709						} );
27710					}
27711				}
27712			}
27713			else {
27714				// jQuery selector on the nodes
27715				$( nodes ).filter( selector ).each( function () {
27716					ret.push( {
27717						inst: inst,
27718						node: this
27719					} );
27720				} );
27721			}
27722		}
27723		else if ( typeof selector === 'object' && selector.nodeName ) {
27724			// Node selector
27725			var idx = $.inArray( selector, nodes );
27726
27727			if ( idx !== -1 ) {
27728				ret.push( {
27729					inst: inst,
27730					node: nodes[ idx ]
27731				} );
27732			}
27733		}
27734	};
27735
27736
27737	for ( var i=0, ien=insts.length ; i<ien ; i++ ) {
27738		var inst = insts[i];
27739
27740		run( selector, inst );
27741	}
27742
27743	return ret;
27744};
27745
27746/**
27747 * Default function used for formatting output data.
27748 * @param {*} str Data to strip
27749 */
27750Buttons.stripData = function ( str, config ) {
27751	if ( typeof str !== 'string' ) {
27752		return str;
27753	}
27754
27755	// Always remove script tags
27756	str = str.replace( /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '' );
27757
27758	// Always remove comments
27759	str = str.replace( /<!\-\-.*?\-\->/g, '' );
27760
27761	if ( ! config || config.stripHtml ) {
27762		str = str.replace( /<[^>]*>/g, '' );
27763	}
27764
27765	if ( ! config || config.trim ) {
27766		str = str.replace( /^\s+|\s+$/g, '' );
27767	}
27768
27769	if ( ! config || config.stripNewlines ) {
27770		str = str.replace( /\n/g, ' ' );
27771	}
27772
27773	if ( ! config || config.decodeEntities ) {
27774		_exportTextarea.innerHTML = str;
27775		str = _exportTextarea.value;
27776	}
27777
27778	return str;
27779};
27780
27781
27782/**
27783 * Buttons defaults. For full documentation, please refer to the docs/option
27784 * directory or the DataTables site.
27785 * @type {Object}
27786 * @static
27787 */
27788Buttons.defaults = {
27789	buttons: [ 'copy', 'excel', 'csv', 'pdf', 'print' ],
27790	name: 'main',
27791	tabIndex: 0,
27792	dom: {
27793		container: {
27794			tag: 'div',
27795			className: 'dt-buttons'
27796		},
27797		collection: {
27798			tag: 'div',
27799			className: ''
27800		},
27801		button: {
27802			tag: 'button',
27803			className: 'dt-button',
27804			active: 'active',
27805			disabled: 'disabled'
27806		},
27807		buttonLiner: {
27808			tag: 'span',
27809			className: ''
27810		}
27811	}
27812};
27813
27814/**
27815 * Version information
27816 * @type {string}
27817 * @static
27818 */
27819Buttons.version = '1.7.1';
27820
27821
27822$.extend( _dtButtons, {
27823	collection: {
27824		text: function ( dt ) {
27825			return dt.i18n( 'buttons.collection', 'Collection' );
27826		},
27827		className: 'buttons-collection',
27828		init: function ( dt, button, config ) {
27829			button.attr( 'aria-expanded', false );
27830		},
27831		action: function ( e, dt, button, config ) {
27832			e.stopPropagation();
27833
27834			if ( config._collection.parents('body').length ) {
27835				this.popover(false, config);
27836			}
27837			else {
27838				this.popover(config._collection, config);
27839			}
27840		},
27841		attr: {
27842			'aria-haspopup': true
27843		}
27844		// Also the popover options, defined in Buttons.popover
27845	},
27846	copy: function ( dt, conf ) {
27847		if ( _dtButtons.copyHtml5 ) {
27848			return 'copyHtml5';
27849		}
27850	},
27851	csv: function ( dt, conf ) {
27852		if ( _dtButtons.csvHtml5 && _dtButtons.csvHtml5.available( dt, conf ) ) {
27853			return 'csvHtml5';
27854		}
27855	},
27856	excel: function ( dt, conf ) {
27857		if ( _dtButtons.excelHtml5 && _dtButtons.excelHtml5.available( dt, conf ) ) {
27858			return 'excelHtml5';
27859		}
27860	},
27861	pdf: function ( dt, conf ) {
27862		if ( _dtButtons.pdfHtml5 && _dtButtons.pdfHtml5.available( dt, conf ) ) {
27863			return 'pdfHtml5';
27864		}
27865	},
27866	pageLength: function ( dt ) {
27867		var lengthMenu = dt.settings()[0].aLengthMenu;
27868		var vals = [];
27869		var lang = [];
27870		var text = function ( dt ) {
27871			return dt.i18n( 'buttons.pageLength', {
27872				"-1": 'Show all rows',
27873				_:    'Show %d rows'
27874			}, dt.page.len() );
27875		};
27876
27877		// Support for DataTables 1.x 2D array
27878		if (Array.isArray( lengthMenu[0] )) {
27879			vals = lengthMenu[0];
27880			lang = lengthMenu[1];
27881		}
27882		else {
27883			for (var i=0 ; i<lengthMenu.length ; i++) {
27884				var option = lengthMenu[i];
27885
27886				// Support for DataTables 2 object in the array
27887				if ($.isPlainObject(option)) {
27888					vals.push(option.value);
27889					lang.push(option.label);
27890				}
27891				else {
27892					vals.push(option);
27893					lang.push(option);
27894				}
27895			}
27896		}
27897
27898		return {
27899			extend: 'collection',
27900			text: text,
27901			className: 'buttons-page-length',
27902			autoClose: true,
27903			buttons: $.map( vals, function ( val, i ) {
27904				return {
27905					text: lang[i],
27906					className: 'button-page-length',
27907					action: function ( e, dt ) {
27908						dt.page.len( val ).draw();
27909					},
27910					init: function ( dt, node, conf ) {
27911						var that = this;
27912						var fn = function () {
27913							that.active( dt.page.len() === val );
27914						};
27915
27916						dt.on( 'length.dt'+conf.namespace, fn );
27917						fn();
27918					},
27919					destroy: function ( dt, node, conf ) {
27920						dt.off( 'length.dt'+conf.namespace );
27921					}
27922				};
27923			} ),
27924			init: function ( dt, node, conf ) {
27925				var that = this;
27926				dt.on( 'length.dt'+conf.namespace, function () {
27927					that.text( conf.text );
27928				} );
27929			},
27930			destroy: function ( dt, node, conf ) {
27931				dt.off( 'length.dt'+conf.namespace );
27932			}
27933		};
27934	}
27935} );
27936
27937
27938/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
27939 * DataTables API
27940 *
27941 * For complete documentation, please refer to the docs/api directory or the
27942 * DataTables site
27943 */
27944
27945// Buttons group and individual button selector
27946DataTable.Api.register( 'buttons()', function ( group, selector ) {
27947	// Argument shifting
27948	if ( selector === undefined ) {
27949		selector = group;
27950		group = undefined;
27951	}
27952
27953	this.selector.buttonGroup = group;
27954
27955	var res = this.iterator( true, 'table', function ( ctx ) {
27956		if ( ctx._buttons ) {
27957			return Buttons.buttonSelector(
27958				Buttons.instanceSelector( group, ctx._buttons ),
27959				selector
27960			);
27961		}
27962	}, true );
27963
27964	res._groupSelector = group;
27965	return res;
27966} );
27967
27968// Individual button selector
27969DataTable.Api.register( 'button()', function ( group, selector ) {
27970	// just run buttons() and truncate
27971	var buttons = this.buttons( group, selector );
27972
27973	if ( buttons.length > 1 ) {
27974		buttons.splice( 1, buttons.length );
27975	}
27976
27977	return buttons;
27978} );
27979
27980// Active buttons
27981DataTable.Api.registerPlural( 'buttons().active()', 'button().active()', function ( flag ) {
27982	if ( flag === undefined ) {
27983		return this.map( function ( set ) {
27984			return set.inst.active( set.node );
27985		} );
27986	}
27987
27988	return this.each( function ( set ) {
27989		set.inst.active( set.node, flag );
27990	} );
27991} );
27992
27993// Get / set button action
27994DataTable.Api.registerPlural( 'buttons().action()', 'button().action()', function ( action ) {
27995	if ( action === undefined ) {
27996		return this.map( function ( set ) {
27997			return set.inst.action( set.node );
27998		} );
27999	}
28000
28001	return this.each( function ( set ) {
28002		set.inst.action( set.node, action );
28003	} );
28004} );
28005
28006// Enable / disable buttons
28007DataTable.Api.register( ['buttons().enable()', 'button().enable()'], function ( flag ) {
28008	return this.each( function ( set ) {
28009		set.inst.enable( set.node, flag );
28010	} );
28011} );
28012
28013// Disable buttons
28014DataTable.Api.register( ['buttons().disable()', 'button().disable()'], function () {
28015	return this.each( function ( set ) {
28016		set.inst.disable( set.node );
28017	} );
28018} );
28019
28020// Get button nodes
28021DataTable.Api.registerPlural( 'buttons().nodes()', 'button().node()', function () {
28022	var jq = $();
28023
28024	// jQuery will automatically reduce duplicates to a single entry
28025	$( this.each( function ( set ) {
28026		jq = jq.add( set.inst.node( set.node ) );
28027	} ) );
28028
28029	return jq;
28030} );
28031
28032// Get / set button processing state
28033DataTable.Api.registerPlural( 'buttons().processing()', 'button().processing()', function ( flag ) {
28034	if ( flag === undefined ) {
28035		return this.map( function ( set ) {
28036			return set.inst.processing( set.node );
28037		} );
28038	}
28039
28040	return this.each( function ( set ) {
28041		set.inst.processing( set.node, flag );
28042	} );
28043} );
28044
28045// Get / set button text (i.e. the button labels)
28046DataTable.Api.registerPlural( 'buttons().text()', 'button().text()', function ( label ) {
28047	if ( label === undefined ) {
28048		return this.map( function ( set ) {
28049			return set.inst.text( set.node );
28050		} );
28051	}
28052
28053	return this.each( function ( set ) {
28054		set.inst.text( set.node, label );
28055	} );
28056} );
28057
28058// Trigger a button's action
28059DataTable.Api.registerPlural( 'buttons().trigger()', 'button().trigger()', function () {
28060	return this.each( function ( set ) {
28061		set.inst.node( set.node ).trigger( 'click' );
28062	} );
28063} );
28064
28065// Button resolver to the popover
28066DataTable.Api.register( 'button().popover()', function (content, options) {
28067	return this.map( function ( set ) {
28068		return set.inst._popover( content, this.button(this[0].node), options );
28069	} );
28070} );
28071
28072// Get the container elements
28073DataTable.Api.register( 'buttons().containers()', function () {
28074	var jq = $();
28075	var groupSelector = this._groupSelector;
28076
28077	// We need to use the group selector directly, since if there are no buttons
28078	// the result set will be empty
28079	this.iterator( true, 'table', function ( ctx ) {
28080		if ( ctx._buttons ) {
28081			var insts = Buttons.instanceSelector( groupSelector, ctx._buttons );
28082
28083			for ( var i=0, ien=insts.length ; i<ien ; i++ ) {
28084				jq = jq.add( insts[i].container() );
28085			}
28086		}
28087	} );
28088
28089	return jq;
28090} );
28091
28092DataTable.Api.register( 'buttons().container()', function () {
28093	// API level of nesting is `buttons()` so we can zip into the containers method
28094	return this.containers().eq(0);
28095} );
28096
28097// Add a new button
28098DataTable.Api.register( 'button().add()', function ( idx, conf ) {
28099	var ctx = this.context;
28100
28101	// Don't use `this` as it could be empty - select the instances directly
28102	if ( ctx.length ) {
28103		var inst = Buttons.instanceSelector( this._groupSelector, ctx[0]._buttons );
28104
28105		if ( inst.length ) {
28106			inst[0].add( conf, idx );
28107		}
28108	}
28109
28110	return this.button( this._groupSelector, idx );
28111} );
28112
28113// Destroy the button sets selected
28114DataTable.Api.register( 'buttons().destroy()', function () {
28115	this.pluck( 'inst' ).unique().each( function ( inst ) {
28116		inst.destroy();
28117	} );
28118
28119	return this;
28120} );
28121
28122// Remove a button
28123DataTable.Api.registerPlural( 'buttons().remove()', 'buttons().remove()', function () {
28124	this.each( function ( set ) {
28125		set.inst.remove( set.node );
28126	} );
28127
28128	return this;
28129} );
28130
28131// Information box that can be used by buttons
28132var _infoTimer;
28133DataTable.Api.register( 'buttons.info()', function ( title, message, time ) {
28134	var that = this;
28135
28136	if ( title === false ) {
28137		this.off('destroy.btn-info');
28138		_fadeOut(
28139			$('#datatables_buttons_info'),
28140			400,
28141			function () {
28142				$(this).remove();
28143			}
28144		);
28145		clearTimeout( _infoTimer );
28146		_infoTimer = null;
28147
28148		return this;
28149	}
28150
28151	if ( _infoTimer ) {
28152		clearTimeout( _infoTimer );
28153	}
28154
28155	if ( $('#datatables_buttons_info').length ) {
28156		$('#datatables_buttons_info').remove();
28157	}
28158
28159	title = title ? '<h2>'+title+'</h2>' : '';
28160
28161	_fadeIn(
28162		$('<div id="datatables_buttons_info" class="dt-button-info"/>')
28163			.html( title )
28164			.append( $('<div/>')[ typeof message === 'string' ? 'html' : 'append' ]( message ) )
28165			.css( 'display', 'none' )
28166			.appendTo( 'body' )
28167	);
28168
28169	if ( time !== undefined && time !== 0 ) {
28170		_infoTimer = setTimeout( function () {
28171			that.buttons.info( false );
28172		}, time );
28173	}
28174
28175	this.on('destroy.btn-info', function () {
28176		that.buttons.info(false);
28177	});
28178
28179	return this;
28180} );
28181
28182// Get data from the table for export - this is common to a number of plug-in
28183// buttons so it is included in the Buttons core library
28184DataTable.Api.register( 'buttons.exportData()', function ( options ) {
28185	if ( this.context.length ) {
28186		return _exportData( new DataTable.Api( this.context[0] ), options );
28187	}
28188} );
28189
28190// Get information about the export that is common to many of the export data
28191// types (DRY)
28192DataTable.Api.register( 'buttons.exportInfo()', function ( conf ) {
28193	if ( ! conf ) {
28194		conf = {};
28195	}
28196
28197	return {
28198		filename: _filename( conf ),
28199		title: _title( conf ),
28200		messageTop: _message(this, conf.message || conf.messageTop, 'top'),
28201		messageBottom: _message(this, conf.messageBottom, 'bottom')
28202	};
28203} );
28204
28205
28206
28207/**
28208 * Get the file name for an exported file.
28209 *
28210 * @param {object}	config Button configuration
28211 * @param {boolean} incExtension Include the file name extension
28212 */
28213var _filename = function ( config )
28214{
28215	// Backwards compatibility
28216	var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined && config.title !== null && config.title !== '' ?
28217		config.title :
28218		config.filename;
28219
28220	if ( typeof filename === 'function' ) {
28221		filename = filename();
28222	}
28223
28224	if ( filename === undefined || filename === null ) {
28225		return null;
28226	}
28227
28228	if ( filename.indexOf( '*' ) !== -1 ) {
28229		filename = filename.replace( '*', $('head > title').text() ).trim();
28230	}
28231
28232	// Strip characters which the OS will object to
28233	filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, "");
28234
28235	var extension = _stringOrFunction( config.extension );
28236	if ( ! extension ) {
28237		extension = '';
28238	}
28239
28240	return filename + extension;
28241};
28242
28243/**
28244 * Simply utility method to allow parameters to be given as a function
28245 *
28246 * @param {undefined|string|function} option Option
28247 * @return {null|string} Resolved value
28248 */
28249var _stringOrFunction = function ( option )
28250{
28251	if ( option === null || option === undefined ) {
28252		return null;
28253	}
28254	else if ( typeof option === 'function' ) {
28255		return option();
28256	}
28257	return option;
28258};
28259
28260/**
28261 * Get the title for an exported file.
28262 *
28263 * @param {object} config	Button configuration
28264 */
28265var _title = function ( config )
28266{
28267	var title = _stringOrFunction( config.title );
28268
28269	return title === null ?
28270		null : title.indexOf( '*' ) !== -1 ?
28271			title.replace( '*', $('head > title').text() || 'Exported data' ) :
28272			title;
28273};
28274
28275var _message = function ( dt, option, position )
28276{
28277	var message = _stringOrFunction( option );
28278	if ( message === null ) {
28279		return null;
28280	}
28281
28282	var caption = $('caption', dt.table().container()).eq(0);
28283	if ( message === '*' ) {
28284		var side = caption.css( 'caption-side' );
28285		if ( side !== position ) {
28286			return null;
28287		}
28288
28289		return caption.length ?
28290			caption.text() :
28291			'';
28292	}
28293
28294	return message;
28295};
28296
28297
28298
28299
28300var _exportTextarea = $('<textarea/>')[0];
28301var _exportData = function ( dt, inOpts )
28302{
28303	var config = $.extend( true, {}, {
28304		rows:           null,
28305		columns:        '',
28306		modifier:       {
28307			search: 'applied',
28308			order:  'applied'
28309		},
28310		orthogonal:     'display',
28311		stripHtml:      true,
28312		stripNewlines:  true,
28313		decodeEntities: true,
28314		trim:           true,
28315		format:         {
28316			header: function ( d ) {
28317				return Buttons.stripData( d, config );
28318			},
28319			footer: function ( d ) {
28320				return Buttons.stripData( d, config );
28321			},
28322			body: function ( d ) {
28323				return Buttons.stripData( d, config );
28324			}
28325		},
28326		customizeData: null
28327	}, inOpts );
28328
28329	var header = dt.columns( config.columns ).indexes().map( function (idx) {
28330		var el = dt.column( idx ).header();
28331		return config.format.header( el.innerHTML, idx, el );
28332	} ).toArray();
28333
28334	var footer = dt.table().footer() ?
28335		dt.columns( config.columns ).indexes().map( function (idx) {
28336			var el = dt.column( idx ).footer();
28337			return config.format.footer( el ? el.innerHTML : '', idx, el );
28338		} ).toArray() :
28339		null;
28340	
28341	// If Select is available on this table, and any rows are selected, limit the export
28342	// to the selected rows. If no rows are selected, all rows will be exported. Specify
28343	// a `selected` modifier to control directly.
28344	var modifier = $.extend( {}, config.modifier );
28345	if ( dt.select && typeof dt.select.info === 'function' && modifier.selected === undefined ) {
28346		if ( dt.rows( config.rows, $.extend( { selected: true }, modifier ) ).any() ) {
28347			$.extend( modifier, { selected: true } )
28348		}
28349	}
28350
28351	var rowIndexes = dt.rows( config.rows, modifier ).indexes().toArray();
28352	var selectedCells = dt.cells( rowIndexes, config.columns );
28353	var cells = selectedCells
28354		.render( config.orthogonal )
28355		.toArray();
28356	var cellNodes = selectedCells
28357		.nodes()
28358		.toArray();
28359
28360	var columns = header.length;
28361	var rows = columns > 0 ? cells.length / columns : 0;
28362	var body = [];
28363	var cellCounter = 0;
28364
28365	for ( var i=0, ien=rows ; i<ien ; i++ ) {
28366		var row = [ columns ];
28367
28368		for ( var j=0 ; j<columns ; j++ ) {
28369			row[j] = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] );
28370			cellCounter++;
28371		}
28372
28373		body[i] = row;
28374	}
28375
28376	var data = {
28377		header: header,
28378		footer: footer,
28379		body:   body
28380	};
28381
28382	if ( config.customizeData ) {
28383		config.customizeData( data );
28384	}
28385
28386	return data;
28387};
28388
28389
28390/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
28391 * DataTables interface
28392 */
28393
28394// Attach to DataTables objects for global access
28395$.fn.dataTable.Buttons = Buttons;
28396$.fn.DataTable.Buttons = Buttons;
28397
28398
28399
28400// DataTables creation - check if the buttons have been defined for this table,
28401// they will have been if the `B` option was used in `dom`, otherwise we should
28402// create the buttons instance here so they can be inserted into the document
28403// using the API. Listen for `init` for compatibility with pre 1.10.10, but to
28404// be removed in future.
28405$(document).on( 'init.dt plugin-init.dt', function (e, settings) {
28406	if ( e.namespace !== 'dt' ) {
28407		return;
28408	}
28409
28410	var opts = settings.oInit.buttons || DataTable.defaults.buttons;
28411
28412	if ( opts && ! settings._buttons ) {
28413		new Buttons( settings, opts ).container();
28414	}
28415} );
28416
28417function _init ( settings, options ) {
28418	var api = new DataTable.Api( settings );
28419	var opts = options
28420		? options
28421		: api.init().buttons || DataTable.defaults.buttons;
28422
28423	return new Buttons( api, opts ).container();
28424}
28425
28426// DataTables `dom` feature option
28427DataTable.ext.feature.push( {
28428	fnInit: _init,
28429	cFeature: "B"
28430} );
28431
28432// DataTables 2 layout feature
28433if ( DataTable.ext.features ) {
28434	DataTable.ext.features.register( 'buttons', _init );
28435}
28436
28437
28438return Buttons;
28439}));
28440
28441
28442/***/ }),
28443/* 5 */,
28444/* 6 */,
28445/* 7 */
28446/***/ (function(module, exports, __webpack_require__) {
28447
28448"use strict";
28449
28450
28451__webpack_require__(31);
28452
28453var _frontendExporter = __webpack_require__(8);
28454
28455var _frontendExporter2 = _interopRequireDefault(_frontendExporter);
28456
28457var _reportingDashboard = __webpack_require__(9);
28458
28459var _reportingDashboard2 = _interopRequireDefault(_reportingDashboard);
28460
28461function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28462
28463// import loadQuizData from './quiz-data';
28464
28465var exporter = new _frontendExporter2.default();
28466// var data_loader = new loadQuizData();
28467// cspell:ignore livesearch .
28468var dashboard_instance = new _reportingDashboard2.default();
28469
28470exporter.downloadReport('.qre-export');
28471// data_loader.onQuizLoad( '.qre_quiz_data_container', '.quiz_load' );
28472// data_loader.onUserChange( '.UserID' );
28473
28474/*New Dashboard Logic*/
28475// dashboard_instance.toggleDuration(
28476// 	'.quiz-report-filters',
28477// 	'.date-filter input[type=checkbox]'
28478// );
28479// dashboard_instance.initDatepicker(
28480// 	['.quiz-report-filters input[name=from_date]', '.quiz-report-filters input[name=to_date]'] );
28481dashboard_instance.livesearch('.quiz-report-filters #qre-search-field', '.search_result_type', '.search_result_id');
28482dashboard_instance.showDatatable('#qre_summarized_data');
28483dashboard_instance.paginateReportsTable('.pagination-form', 'select.limit', '.pagination-section input.page', '.pagination-section button.previous-page', '.pagination-section button.next-page');
28484// dashboard_instance.customDatepicker(
28485// 	['.custom-report-filters input[name=enrollment_from]', '.custom-report-filters input[name=enrollment_to]'] );
28486// dashboard_instance.customDatepicker(
28487// 	['.custom-report-filters input[name=completion_from]', '.custom-report-filters input[name=completion_to]'] );
28488// dashboard_instance.saveCustomReports( '.custom-report-filters', '.s
28488ave_config' );
28489// dashboard_instance.toggleFilterGroups( '.custom-report-filters', '.section-control' );
28490// dashboard_instance.previewCustomReport( '.custom-report-filters', '.preview-data', '.save_config' );
28491// dashboard_instance.enableGenerateButton( '.custom-report-filters', '.preview-data' );
28492// dashboard_instance.onScrollStickyElement();
28493dashboard_instance.toggleHiddenRow('#custom-reports', '.accordion-target', '.accordion-trigger');
28494dashboard_instance.showBulkExportModal('.wrld-bulk-export', '.button-bulk-export');
28495
28496/***/ }),
28497/* 8 */
28498/***/ (function(module, exports, __webpack_require__) {
28499
28500"use strict";
28501
28502
28503Object.defineProperty(exports, "__esModule", {
28504	value: true
28505});
28506
28507var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
28508
28509function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28510
28511// cspell:ignore .
28512/**
28513 * This class is used to handle the functionality of exporting in the website frontend.
28514 */
28515/* globals qre_export_obj: false */
28516var frontendExporter = function () {
28517	function frontendExporter() {
28518		_classCallCheck(this, frontendExporter);
28519	}
28520	/**
28521  * This method is used to handle the export feature in the website frontend.
28522  * @param  {string} selector The selector of the download link.
28523  */
28524
28525
28526	_createClass(frontendExporter, [{
28527		key: 'downloadReport',
28528		value: function downloadReport(selector) {
28529			var instance = this;
28530			jQuery('body').on('click', selector, function (event) {
28531				event.preventDefault();
28532				var $self = jQuery(this);
28533				var ref_id = $self.attr('data-ref_id');
28534				var format = '';
28535				if ($self.hasClass('qre-download-csv')) {
28536					format = 'csv';
28537				}
28538				if ($self.hasClass('qre-download-xlsx')) {
28539					format = 'xlsx';
28540				}
28541				jQuery('#qre_exp_form_' + qre_export_obj.quiz_export_nonce).remove(); // removes previously generated form
28542				jQuery('#qre_error').remove(); // removes previously generated errors
28543				if (ref_id !== '' && ref_id !== undefined) {
28544					var refs = ref_id.split(',');
28545					if (refs.length > 1) {
28546						if (typeof jQuery('.entry-content').block !== 'undefined') {
28547							jQuery('.entry-content').block({
28548								message: '<h4>Processing...</h4>',
28549								css: { border: '3px solid #a00' }
28550							});
28551						}
28552						window.prepareZipFile.prototype.prepareZip(format, ref_id, 0, qre_export_obj.ajax_url, qre_export_obj.quiz_export_nonce);
28553					} else {
28554						$self.find('form').remove();
28555						var html_str = '<form id="qre_exp_form_' + qre_export_obj.quiz_export_nonce + '" method="post" action="" target="_blank" style="display:none;">' + '<input name="file_format" type="hidden" value="' + format + '">' + '<input name="ref_id" type="hidden" value="' + ref_id + '">' + '<input name="quiz_export_nonce" type="hidden" value="' + qre_export_obj.quiz_export_nonce + '">' + '</form>';
28556						$self.append(html_str);
28557						$self.find('form').submit();
28558						jQuery('#qre_loader').remove();
28559					}
28560				}
28561			});
28562		}
28563	}]);
28564
28565	return frontendExporter;
28566}();
28567
28568exports.default = frontendExporter;
28569
28570/***/ }),
28571/* 9 */
28572/***/ (function(module, exports, __webpack_require__) {
28573
28574"use strict";
28575
28576
28577Object.defineProperty(exports, "__esModule", {
28578	value: true
28579});
28580
28581var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
28582
28583var _resultFilters = __webpack_require__(10);
28584
28585var _resultFilters2 = _interopRequireDefault(_resultFilters);
28586
28587var _customReports = __webpack_require__(11);
28588
28589var _customReports2 = _interopRequireDefault(_customReports);
28590
28591__webpack_require__(4);
28592
28593__webpack_require__(12);
28594
28595function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28596
28597function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28598
28599// cspell:ignore livesearch lTfgtip .
28600/**
28601 * This class iz used to load quiz data and other UI events related to the shortcode.
28602 */
28603/*globals quiz_statistics_data:false, qre_export_obj: false*/
28604window.$ = jQuery;
28605// var dt2 = require('datatables.net-buttons');
28606var dt = __webpack_require__(13);
28607var JSZip = __webpack_require__(16);
28608window.$.fn.DataTable = dt;
28609window.$.fn.DataTable.Buttons.jszip(JSZip);
28610
28611jQuery.fn.outerHTML = function () {
28612	return jQuery('<div />').append(this.eq(0).clone()).html();
28613};
28614
28615var reportingDashboard = function () {
28616	function reportingDashboard() {
28617		_classCallCheck(this, reportingDashboard);
28618
28619		this.result_filters = new _resultFilters2.default();
28620		this.custom_reports = new _customReports2.default();
28621		this.quiz_reports_table = null;
28622		this.custom_reports_table = null;
28623	}
28624
28625	_createClass(reportingDashboard, [{
28626		key: 'toggleDuration',
28627		value: function toggleDuration(container, selector) {
28628			this.result_filters.toggle(container, selector);
28629		}
28630	}, {
28631		key: 'initDatepicker',
28632		value: function initDatepicker(selectors) {
28633			this.result_filters.datepicker_init(selectors);
28634		}
28635	}, {
28636		key: 'livesearch',
28637		value: function livesearch(selector, type_selector, id_selector) {
28638			this.result_filters.search(selector);
28639			this.result_filters.select_result(selector, type_selector, id_selector);
28640			this.result_filters.reset_search(selector, type_selector, id_selector);
28641		}
28642	}, {
28643		key: 'showDatatable',
28644		value: function showDatatable(selector) {
28645			var instance = this;
28646			jQuery(document).ready(function () {
28647				if (typeof quiz_statistics_data === 'undefined') {
28648					return;
28649				}
28650				var $quiz_title = null;
28651				var $quiz_title_text = '';
28652				var $user_name = null;
28653				var $user_name_text = '';
28654				for (var i = 0; i < quiz_statistics_data.data.length; i++) {
28655					if (jQuery(window).width() < 1500) {
28656						$quiz_title = jQuery(quiz_statistics_data.data[i].quiz_title);
28657						$quiz_title_text = $quiz_title.text().substring(0, 30);
28658						if ($quiz_title.text().length > 30) {
28659							$quiz_title_text += '...';
28660						}
28661						$quiz_title.text($quiz_title_text);
28662						quiz_statistics_data.data[i].quiz_title = $quiz_title.outerHTML();
28663						$user_name = jQuery(quiz_statistics_data.data[i].user_name);
28664						$user_name_text = $user_name.text().substring(0, 30);
28665						if ($user_name.text().length > 30) {
28666							$user_name_text += '...';
28667						}
28668						$user_name.text($user_name_text);
28669						quiz_statistics_data.data[i].user_name = $user_name.outerHTML();
28670					}
28671					quiz_statistics_data.data[i].index = i + 1;
28672				}
28673				instance.quiz_reports_table = jQuery(selector).DataTable({
28674					paging: false,
28675					ordering: false,
28676					searching: false,
28677					info: false,
28678					responsive: false,
28679					data: quiz_statistics_data.data,
28680					columns: [{ data: 'index', visible: true }, { data: 'quiz_title', visible: true }, { data: 'user_name', visible: true }, { data: 'date_attempt', visible: true }, { data: 'score', visible: true }, { data: 'time_taken', visible: true }, { data: 'link', visible: true }],
28681					columnDefs: [{
28682						targets: [0, 3, 4, 5, 6],
28683						className: 'dt-center'
28684					}, {
28685						targets: [1, 2],
28686						className: 'dt-left'
28687					}],
28688					language: {
28689						emptyTable: quiz_statistics_data.no_data
28690					}
28691				});
28692			});
28693		}
28694	}, {
28695		key: 'paginateReportsTable',
28696		value: function paginateReportsTable(pagination_form, limit_selector, page_number_selector, previous_page_btn, next_page_button) {
28697			var instance = this;
28698			jQuery(document).ready(function () {
28699				instance.result_filters.change_entry_count(pagination_form, limit_selector);
28700				instance.result_filters.change_page_number(pagination_form, page_number_selector, previous_page_btn, next_page_button);
28701			});
28702		}
28703	}, {
28704		key: 'customDatepicker',
28705		value: function customDatepicker(selectors) {
28706			this.custom_reports.datepicker_init(selectors);
28707		}
28708	}, {
28709		key: 'saveCustomReports',
28710		value: function saveCustomReports(container, button) {
28711			var instance = this;
28712			jQuery(document).ready(function () {
28713				instance.custom_reports.save_config(container, button);
28714			});
28715		}
28716	}, {
28717		key: 'toggleFilterGroups',
28718		value: function toggleFilterGroups(container, button) {
28719			var instance = this;
28720			jQuery(document).ready(function () {
28721				instance.custom_reports.toggle_filter_group(container, button);
28722			});
28723		}
28724	}, {
28725		key: 'previewCustomReport',
28726		value: function previewCustomReport(container, preview_button, save_button) {
28727			var instance = this;
28728			jQuery(document).ready(function () {
28729				instance.custom_reports.fetch_data(preview_button, save_button);
28730				jQuery(document).on('custom_report_created', function (event, dat) {
28731					/*if ( jQuery.fn.DataTable.isDataTable( '#custom-reports' ) ) {
28732     	instance.custom_reports_table.fnDestroy();
28733     	column_slugs = [];
28734     	jQuery( container ).find( 'input[type="checkbox"]' ).each( function( ind, ele ) {
28735     		if ( jQuery( ele ).is( ':checked' ) ) {
28736     			if ( jQuery( '#custom-reports' ).find( 'th[data-column=' + jQuery( ele ).attr( 'name' ) + ']' ).length === 0 ) {
28737     				jQuery( 'table thead tr' ).append(
28738     					'<th data-column="' + jQuery( ele ).attr( 'name' ) + '">' +
28739     						jQuery( 'label[for=' + jQuery( ele ).attr( 'name' ) + ']' ).text() +
28740     					'</th>'
28741     				);
28742     			}
28743     		} else {
28744     			if ( jQuery( '#custom-reports' ).find( 'th[data-column=' + jQuery( ele ).attr( 'name' ) + ']' ).length > 0 ) {
28745     				var $table_column = jQuery( 'table th[data-column="' + jQuery( ele ).attr( 'name' ) + '"]' );
28746     				var cell_index = $table_column.index();
28747     				$table_column.closest('table').find('tr').each(function() {
28748     			        if ( typeof this.cells[ cell_index ] !== 'undefined' ) {
28749     				        this.removeChild( this.cells[ cell_index ] );
28750     			        }
28751     			    });
28752     			}
28753     		}
28754     	} );
28755     }*/
28756					jQuery('#custom-reports').show();
28757					/*var headings = jQuery('#custom-reports th');
28758     var column_slugs = [];
28759     headings.each(function(index, ele){
28760     	column_slugs.push({ data: jQuery(ele).attr('data-column'), className: 'px200' });
28761     });
28762     instance.custom_reports_table = jQuery( '#custom-reports' ).DataTable(
28763     {
28764                  responsive: true,
28765     	dom: '<"html5buttons"B>lTfgtip',
28766            buttons: [
28767             { extend: 'csv', text: qre_export_obj.download_csv_text},
28768             { extend: 'excel', text: qre_export_obj.download_xls_text },
28769            ],
28770                  'bDestroy': true,
28771     	data: dat,
28772     	columns: column_slugs,
28773     	destroy: true,
28774     });
28775     jQuery('.dt-buttons').appendTo( '.custom-report-buttons' );*/
28776				});
28777			});
28778		}
28779	}, {
28780		key: 'enableGenerateButton',
28781		value: function enableGenerateButton(container, preview_button) {
28782			var instance = this;
28783			jQuery(container).on('change', 'select', function () {
28784				jQuery(preview_button).css('visibility', 'visible');
28785			});
28786			jQuery(container).on('change click', 'input[type=checkbox], input[type=text]', function () {
28787				jQuery(preview_button).css('visibility', 'visible');
28788			});
28789			/*jQuery( container ).on( 'change', 'input[type=checkbox]', function() {
28790   	if ( jQuery( this ).is( ':checked' ) ) {
28791   		if ( ! jQuery.fn.DataTable.isDataTable( '#custom-reports' ) ) {
28792   			jQuery( 'table thead tr' ).append(
28793   				'<th data-column="' + jQuery( this ).attr( 'name' ) + '">' +
28794   					jQuery( 'label[for=' + jQuery( this ).attr( 'name' ) + ']' ).text() +
28795   				'</th>'
28796   			);
28797   		}
28798   	} else {
28799   		if ( ! jQuery.fn.DataTable.isDataTable( '#custom-reports' ) ) {
28800   			var $table_column = jQuery( 'table th[data-column="' + jQuery(this).attr( 'name' ) + '"]' );
28801   			var cell_index = $table_column.index();
28802   			$table_column.closest('table').find('tr').each(function() {
28803   		        if ( typeof this.cells[ cell_index ] !== 'undefined' ) {
28804   			        this.removeChild( this.cells[ cell_index ] );
28805   		        }
28806   		    });
28807   		}
28808   	}
28809   } );*/
28810		}
28811	}, {
28812		key: 'onScrollStickyElement',
28813		value: function onScrollStickyElement() {
28814			jQuery(window).on('load resize', function () {
28815				var sticky_section = jQuery('.sticky-custom-report-buttons');
28816				if (sticky_section.length === 0) {
28817					return;
28818				}
28819				var sticky = jQuery('.custom-reports-content').offset().top;
28820				jQuery(window).on('scroll', function () {
28821					if (window.pageYOffset > sticky) {
28822						jQuery('.dt-buttons').appendTo('.sticky-custom-report-buttons');
28823						sticky_section.addClass('sticky');
28824					} else {
28825						jQuery('.dt-buttons').appendTo('.custom-report-buttons');
28826						sticky_section.removeClass('sticky');
28827					}
28828				});
28829			});
28830		}
28831	}, {
28832		key: 'toggleHiddenRow',
28833		value: function toggleHiddenRow(container, target, selector) {
28834			jQuery(document).on('click', selector, function (event) {
28835				var $self = jQuery(this);
28836				var $parent = $self.parents('.row_data');
28837				var $target = $parent.next();
28838				$target.toggleClass('collapse');
28839				$self.toggleClass('active');
28840				$parent.toggleClass('expanded');
28841			});
28842		}
28843	}, {
28844		key: 'showBulkExportModal',
28845		value: function showBulkExportModal(source, target) {
28846			jQuery(document).on('click', source, function () {
28847				jQuery(target).trigger('click');
28848			});
28849		}
28850	}]);
28851
28852	return reportingDashboard;
28853}();
28854
28855exports.default = reportingDashboard;
28856
28857/***/ }),
28858/* 10 */
28859/***/ (function(module, exports, __webpack_require__) {
28860
28861"use strict";
28862
28863
28864Object.defineProperty(exports, "__esModule", {
28865	value: true
28866});
28867
28868var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // cspell:ignore toggleon .
28869/* globals qre_export_obj: false, URLSearchParams: false */
28870
28871
28872var _jsDatepicker = __webpack_require__(3);
28873
28874var _jsDatepicker2 = _interopRequireDefault(_jsDatepicker);
28875
28876function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28877
28878function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28879
28880/**
28881 * This class does all the processing related to filtering results.
28882 */
28883var resultFilters = function () {
28884	function resultFilters() {
28885		_classCallCheck(this, resultFilters);
28886
28887		this.search_string = '';
28888		this.selected_result = {
28889			id: 0,
28890			type: '',
28891			text: ''
28892		};
28893	}
28894	/**
28895  * This method is used to toggle between period and date range filters
28896  * @param  {string} container Container for the input field.
28897  * @param  {string} selector  Hidden checkbox for the Toggle button.
28898  */
28899
28900
28901	_createClass(resultFilters, [{
28902		key: 'toggle',
28903		value: function toggle(container, selector) {
28904			jQuery(container).on('change', selector, function () {
28905				jQuery(this).parents('.date-filter').toggleClass('toggleon');
28906				jQuery(this).parents('.toggle').find('.option').toggleClass('active');
28907			});
28908		}
28909		/**
28910   * This method is used to initialize both the date selectors and establish a date range relation between them.
28911   * @param  {string} selectors Selectors for both the date fields.
28912   */
28913
28914	}, {
28915		key: 'datepicker_init',
28916		value: function datepicker_init(selectors) {
28917			var args = {
28918				id: 1,
28919				formatter: function formatter(input, date, instance) {
28920					instance = instance;
28921					var value = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
28922					input.value = value; // => 'F j, Y'
28923				}
28924			};
28925			var args_clone;
28926			for (var i = 0; i <= selectors.length - 1; i++) {
28927				if (jQuery(selectors[i]).length === 0) {
28928					continue;
28929				}
28930				args_clone = Object.assign({}, args);
28931				if (jQuery(selectors[i]).val().length !== 0) {
28932					args_clone.dateSelected = new Date(jQuery(selectors[i]).val());
28933				}
28934				(0, _jsDatepicker2.default)(selectors[i], args_clone);
28935			}
28936		}
28937		/**
28938   * This method is used to perform the live search operation for the keyword based on quiz title or user.
28939   * @param  {string}
28939 selector Selector for search field.
28940   */
28941
28942	}, {
28943		key: 'search',
28944		value: function search(selector) {
28945			var instance = this;
28946			/* On typing */
28947			jQuery(selector).on('keyup', this.delay(function (event) {
28948				event.stopPropagation();
28949				var query = jQuery(this).val();
28950				var search_field = jQuery(this);
28951				if (query === instance.search_string) {
28952					return;
28953				}
28954				instance.search_string = query;
28955				if (search_field.next().hasClass('search_results') || search_field.next().hasClass('reset_search')) {
28956					search_field.next().remove();
28957				}
28958				if (instance.search_string.length < 3) {
28959					return;
28960				}
28961				jQuery(selector).addClass('searching');
28962				jQuery.ajax({
28963					type: 'POST',
28964					url: qre_export_obj.ajax_url,
28965					timeout: 10000,
28966					retry_count: 0,
28967					retry_limit: 1,
28968					data: {
28969						action: 'qre_live_search',
28970						security: qre_export_obj.search_results_nonce,
28971						query: instance.search_string
28972					},
28973					success: function success(result) {
28974						jQuery(selector).removeClass('searching');
28975						if (!result.success) {
28976							search_field.after('<span class="search_results">' + result.data.message + '</span>');
28977							return;
28978						}
28979						search_field.parent().append('<ul class="search_results"></ul>');
28980						for (var i = 0; i < result.data.length; i++) {
28981							search_field.parent().find('ul').append('<li class="' + result.data[i].icon + '" data-id="' + result.data[i].ID + '" data-type="' + result.data[i].type + '">' + result.data[i].title + '</li>');
28982						}
28983					},
28984					error: function error(xhr, status, error_thrown) {
28985						if (status === 'timeout') {
28986							this.retry_count++;
28987							if (this.retry_count <= this.retry_limit) {
28988								console.log('Retrying');
28989								jQuery.ajax(this);
28990								return;
28991							} else {
28992								console.error('request timed out');
28993								jQuery(selector).removeClass('searching');
28994								search_field.after('<span class="search_results">' + qre_export_obj.timeout_message + '</span>');
28995							}
28996						} else {
28997							console.log(error_thrown);
28998							jQuery(selector).removeClass('searching');
28999							search_field.after('<span class="search_results">' + error_thrown + '</span>');
29000						}
29001					}
29002				});
29003			}, 500));
29004		}
29005		/**
29006   * This method is used to delay a callback by sometime to prevent flooding of events.
29007   * (like keyup or mouse scroll which are frequent events.)
29008   * @param  {Function} fn Callback to delay.
29009   * @param  {number}   ms Time in milliseconds.
29010   * @return {Function}    Same function delayed by required time.
29011   */
29012
29013	}, {
29014		key: 'delay',
29015		value: function delay(fn, ms) {
29016			var timer = 0;
29017			return function () {
29018				clearTimeout(timer);
29019
29020				for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
29021					args[_key] = arguments[_key];
29022				}
29023
29024				timer = setTimeout(fn.bind.apply(fn, [this].concat(args)), ms || 0);
29025			};
29026		}
29027
29028		/**
29029   * This method is used to select a result for further processing.
29030   *
29031   * @param {string} search_input  Selector for search field.
29032   * @param {string} type_selector Selector for hidden input which stores query type.
29033   * @param {string} id_selector   Selector for hidden input which stores query object id.
29034   */
29035
29036	}, {
29037		key: 'select_result',
29038		value: function select_result(search_input, type_selector, id_selector) {
29039			var instance = this;
29040			jQuery(document).on('click', '.search-reports ul.search_results li', function () {
29041				var query = jQuery(this);
29042				if (instance.selected_result.id === query.attr('data-id')) {
29043					return;
29044				}
29045				instance.selected_result.id = query.attr('data-id');
29046				instance.selected_result.type = query.attr('data-type');
29047				instance.selected_result.text = instance.search_string = query.text();
29048				jQuery(search_input).val(instance.selected_result.text);
29049				jQuery(type_selector).val(instance.selected_result.type);
29050				jQuery(id_selector).val(instance.selected_result.id);
29051				if (jQuery(search_input).next().hasClass('search_results')) {
29052					jQuery(search_input).next().remove();
29053				}
29054				jQuery(search_input).after('<span class="reset_search"></span>');
29055			});
29056		}
29057
29058		/**
29059   * This method is used to select a result for further processing.
29060   *
29061   * @param {string}
29061 search_input Selector for search field.
29062   * @param {string} type_selector Selector for hidden input which stores query type.
29063   * @param {string} id_selector   Selector for hidden input which stores query object id.
29064   */
29065
29066	}, {
29067		key: 'reset_search',
29068		value: function reset_search(search_input, type_selector, id_selector) {
29069			var instance = this;
29070			jQuery('body').on('click', '.reset_search', function () {
29071				jQuery(search_input).val('');
29072				jQuery(type_selector).val('');
29073				jQuery(id_selector).val(0);
29074				instance.search_string = '';
29075				instance.selected_result = {
29076					id: 0,
29077					type: '',
29078					text: ''
29079				};
29080				jQuery(this).remove();
29081			});
29082		}
29083
29084		/**
29085   * This method is used to change number of entries shown per page.
29086   * @param  string pagination_form Pagination Form Selector.
29087   * @param  string limit_selector  Limit Dropdown Selector.
29088   */
29089
29090	}, {
29091		key: 'change_entry_count',
29092		value: function change_entry_count(pagination_form, limit_selector) {
29093			var self = this;
29094			jQuery(limit_selector).on('change', function () {
29095				if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) {
29096					jQuery(pagination_form).submit();
29097					return;
29098				}
29099				self.add_filters_to_pagination(pagination_form);
29100				jQuery(pagination_form).submit();
29101			});
29102		}
29103
29104		/**
29105   * This method is used to control pagination inputs.
29106   * @param  string pagination_form      Pagination form Selector
29107   * @param  string page_number_selector Page Number Input Selector
29108   * @param  string previous_page_btn    Previous page button Selector
29109   * @param  string next_page_button     Next page button Selector
29110   */
29111
29112	}, {
29113		key: 'change_page_number',
29114		value: function change_page_number(pagination_form, page_number_selector, previous_page_btn, next_page_button) {
29115			var self = this;
29116			jQuery(page_number_selector).on('change', function () {
29117				var page_number = parseInt(jQuery(this).val());
29118				var max_page_number = parseInt(jQuery(this).attr('data-max'));
29119				if (isNaN(page_number)) {
29120					return false;
29121				}
29122				if (page_number > max_page_number) {
29123					return false;
29124				}
29125				jQuery(pagination_form).find('input[name=pageno]').val(page_number);
29126				if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) {
29127					jQuery(pagination_form).submit();
29128					return;
29129				}
29130				self.add_filters_to_pagination(pagination_form);
29131				jQuery(pagination_form).submit();
29132			});
29133			jQuery(next_page_button).on('click', function () {
29134				var page_number = parseInt(jQuery(page_number_selector).val());
29135				var max_page_number = parseInt(jQuery(page_number_selector).attr('data-max'));
29136				if (page_number === max_page_number) {
29137					jQuery(this).attr('disabled', 'disabled');
29138					return false;
29139				}
29140				jQuery(pagination_form).find('input[name=pageno]').val(page_number + 1);
29141				if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) {
29142					jQuery(pagination_form).submit();
29143					return;
29144				}
29145				self.add_filters_to_pagination(pagination_form);
29146				jQuery(pagination_form).submit();
29147			});
29148			jQuery(previous_page_btn).on('click', function () {
29149				var page_number = parseInt(jQuery(page_number_selector).val());
29150				if (page_number === 1) {
29151					jQuery(this).attr('disabled', 'disabled');
29152					return false;
29153				}
29154				jQuery(pagination_form).find('input[name=pageno]').val(page_number - 1);
29155				if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) {
29156					jQuery(pagination_form).submit();
29157					return;
29158				}
29159				self.add_filters_to_pagination(pagination_form);
29160				jQuery(pagination_form).submit();
29161			});
29162		}
29163
29164		/**
29165   * This method is used to check if a query param exists.
29166   * @param  string field Query Param
29167   */
29168
29169	}, {
29170		key: 'check_query_params',
29171		value: function check_query_params(field) {
29172			var url = window.location.href;
29173			if (url.indexOf('?' + field + '=') !== -1) {
29174				return true;
29175			} else if (url.indexOf('&' + field + '=') !== -1) {
29176				return true;
29177			}
29178			return false;
29179		}
29180
29181		/**
29182   * Add user selected filters to pagination.
29183   * @param string pagination_form Form Selectors.
29184   */
29185
29186	}, {
29187		key: 'add_filters_to_pagination',
29188		value: function add_filters_to_pagination(pagination_form) {
29189			var url_params = new URLSearchParams(window.location.search);
29190			var filters = url_params.keys();
29191			var _iteratorNormalCompletion = true;
29192			var _didIteratorError = false;
29193			var _iteratorError = undefined;
29194
29195			try {
29196				for (var _iterator = filters[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
29197					var param = _step.value;
29198
29199					if (-1 !== jQuery.inArray(param, ['limit', 'pageno'])) {
29200						continue;
29201					}
29202					var input = jQuery('<input>').attr('type', 'hidden').attr('name', param).val(jQuery('[name=' + param + ']').val());
29203					jQuery(pagination_form).append(input);
29204				}
29205			} catch (err) {
29206				_didIteratorError = true;
29207				_iteratorError = err;
29208			} finally {
29209				try {
29210					if (!_iteratorNormalCompletion && _iterator.return) {
29211						_iterator.return();
29212					}
29213				} finally {
29214					if (_didIteratorError) {
29215						throw _iteratorError;
29216					}
29217				}
29218			}
29219		}
29220	}]);
29221
29222	return resultFilters;
29223}();
29224
29225exports.default = resultFilters;
29226
29227/***/ }),
29228/* 11 */
29229/***/ (function(module, exports, __webpack_require__) {
29230
29231"use strict";
29232
29233
29234Object.defineProperty(exports, "__esModule", {
29235	value: true
29236});
29237
29238var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
29239                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * This class iz used to load quiz data and other UI events related to the shortcode.
29240                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
29241/* globals qre_export_obj: false */
29242
29243
29244var _jsDatepicker = __webpack_require__(3);
29245
29246var _jsDatepicker2 = _interopRequireDefault(_jsDatepicker);
29247
29248function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29249
29250function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
29251
29252/**
29253 * This class does all the processing related to filtering results.
29254 */
29255var customReports = function () {
29256	function customReports() {
29257		_classCallCheck(this, customReports);
29258	}
29259
29260	_createClass(customReports, [{
29261		key: 'save_config',
29262		value: function save_config(container, button) {
29263			jQuery(button).on('click', function () {
29264				var form_data = {};
29265
29266				jQuery(container).find('input[type=checkbox]').each(function (ind, el) {
29267					if (jQuery(el).is(':checked')) {
29268						form_data[jQuery(el).attr('name')] = jQuery(el).val();
29269						// form_data.append( jQuery( el ).attr( 'name' ), jQuery( el ).val() );
29270					}
29271				});
29272				jQuery(container).find('select, input[type=text]').each(function (ind, el) {
29273					form_data[jQuery(el).attr('name')] = jQuery(el).val();
29274				});
29275
29276				jQuery(button).attr('disabled', 'disabled');
29277				jQuery.ajax({
29278					type: 'POST',
29279					url: qre_export_obj.ajax_url,
29280					timeout: 10000,
29281					retry_count: 0,
29282					retry_limit: 1,
29283					data: {
29284						action: 'qre_save_filters',
29285						security: qre_export_obj.custom_reports_nonce,
29286						fields: form_data
29287					},
29288					success: function success(result) {
29289						jQuery(button).removeAttr('disabled');
29290						jQuery(document).trigger('custom_reports_config_set');
29291						result = result;
29292					},
29293					error: function error(xhr, status, error_thrown) {
29294						if (status === 'timeout') {
29295							this.retry_count++;
29296							if (this.retry_count <= this.retry_limit) {
29297								console.log('Retrying');
29298								jQuery.ajax(this);
29299								return;
29300							} else {
29301								console.error('request timed out');
29302								jQuery(button).removeAttr('disabled');
29303								jQuery(document).trigger('custom_reports_config_set');
29304							}
29305						} else {
29306							console.log(error_thrown);
29307							jQuery(button).removeAttr('disabled');
29308							jQuery(document).trigger('custom_reports_config_set');
29309						}
29310					}
29311				});
29312			});
29313		}
29314	}, {
29315		key: 'toggle_filter_group',
29316		value: function toggle_filter_group(container, button) {
29317			jQuery(container).on('click', button, function () {
29318				var $this = jQuery(this);
29319				var $all = jQuery(button);
29320				var open = false;
29321				if ($this.hasClass('expanded')) {
29322					open = true;
29323				}
29324				$all.removeClass('expanded');
29325				$all.parents('.section').find('.section-body').removeClass('expanded');
29326				if (!open) {
29327					$this.toggleClass('expanded');
29328					$this.parents('.section').find('.section-body').toggleClass('expanded');
29329				}
29330			});
29331		}
29332	}, {
29333		key: 'fetch_data',
29334		value: function fetch_data(button, save_button) {
29335			jQuery(button).on('click', function () {
29336				jQuery('.custom-reports-content').addClass('loading');
29337				// jQuery( button ).css( 'visibility', 'hidden' );
29338				jQuery(save_button).trigger('click');
29339				setTimeout(function () {
29340					jQuery(button).text(qre_export_obj.preview_report_btn_text);
29341				}, 1000);
29342			});
29343			jQuery(document).on('custom_reports_config_set', function () {
29344				jQuery.ajax({
29345					type: 'GET',
29346					url: window.location.href,
29347					timeout: 60000,
29348					retry_count: 0,
29349					retry_limit: 1,
29350					data: {
29351						action: 'qre_get_filters',
29352						security: qre_export_obj.fetch_custom_reports
29353					},
29354					success: function success(result) {
29355						// if ( ! result.success ) {
29356						// 	jQuery('.custom-reports-content').removeClass('loading');
29357						// 	jQuery( button ).css( 'visibility', 'visible' );
29358						// 	return;
29359						// }
29360						//jQuery('.custom-reports-container').html( jQuery( result ).find( '.custom-reports-container' ).html() );
29361						// jQuery(document).trigger('custom_report_created', [compiled_data] );
29362						// jQuery('.custom-reports-container').html( jQuery( result ).find( '.custom-reports-container' ).html() );
29363						jQuery('.custom-reports-content').removeClass('loading');
29364						window.location.replace(qre_export_obj.first_custom_url);
29365					},
29366					error: function error(xhr, status, error_thrown) {
29367						if (status === 'timeout') {
29368							this.retry_count++;
29369							if (this.retry_count <= this.retry_limit) {
29370								console.log('Retrying');
29371								jQuery.ajax(this);
29372								return;
29373							} else {
29374								console.error('request timed out');
29375								// jQuery( button ).removeAttr( 'disabled' );
29376								jQuery('.custom-reports-content').removeClass('loading');
29377							}
29378						} else {
29379							console.log(error_thrown);
29380							// jQuery( button ).removeAttr( 'disabled' );
29381							jQuery('.custom-reports-content').removeClass('loading');
29382						}
29383					}
29384				});
29385			});
29386		}
29387		/**
29388   * This method is used to initialize both the date selectors and establish a date range relation between them.
29389   * @param  {string} selectors Selectors for both the date fields.
29390   */
29391
29392	}, {
29393		key: 'datepicker_init',
29394		value: function datepicker_init(selectors) {
29395			var did = Math.floor(Math.random() * Math.floor(100));
29396			var args = {
29397				id: did,
29398				formatter: function formatter(input, date, instance) {
29399					instance = instance;
29400					var value = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
29401					input.value = value; // => 'F j, Y'
29402				}
29403			};
29404			var args_clone;
29405			for (var counter_i = 0; counter_i <= selectors.length - 1; counter_i++) {
29406				if (jQuery(selectors[counter_i]).length === 0) {
29407					continue;
29408				}
29409				args_clone = Object.assign({}, args);
29410				if (jQuery(selectors[counter_i]).val().length !== 0) {
29411					args_clone.dateSelected = new Date(jQuery(selectors[counter_i]).val());
29412				}
29413				(0, _jsDatepicker2.default)(selectors[counter_i], args_clone);
29414			}
29415		}
29416	}]);
29417
29418	return customReports;
29419}();
29420
29421exports.default = customReports;
29422
29423/***/ }),
29424/* 12 */
29425/***/ (function(module, exports, __webpack_require__) {
29426
29427var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
29428 * HTML5 export buttons for Buttons and DataTables.
29429 * 2016 SpryMedia Ltd - datatables.net/license
29430 *
29431 * FileSaver.js (1.3.3) - MIT license
29432 * Copyright © 2016 Eli Grey - http://eligrey.com
29433 */
29434
29435(function( factory ){
29436	if ( true ) {
29437		// AMD
29438		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1), __webpack_require__(4)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {
29439			return factory( $, window, document );
29440		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
29441				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
29442	}
29443	else {}
29444}(function( $, window, document, jszip, pdfmake, undefined ) {
29445'use strict';
29446var DataTable = $.fn.dataTable;
29447
29448// Allow the constructor to pass in JSZip and PDFMake from external requires.
29449// Otherwise, use globally defined variables, if they are available.
29450function _jsZip () {
29451	return jszip || window.JSZip;
29452}
29453function _pdfMake () {
29454	return pdfmake || window.pdfMake;
29455}
29456
29457DataTable.Buttons.pdfMake = function (_) {
29458	if ( ! _ ) {
29459		return _pdfMake();
29460	}
29461	pdfmake = _;
29462}
29463
29464DataTable.Buttons.jszip = function (_) {
29465	if ( ! _ ) {
29466		return _jsZip();
29467	}
29468	jszip = _;
29469}
29470
29471
29472/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
29473 * FileSaver.js dependency
29474 */
29475
29476/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
29477
29478var _saveAs = (function(view) {
29479	"use strict";
29480	// IE <10 is explicitly unsupported
29481	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
29482		return;
29483	}
29484	var
29485		  doc = view.document
29486		  // only get URL when necessary in case Blob.js hasn't overridden it yet
29487		, get_URL = function() {
29488			return view.URL || view.webkitURL || view;
29489		}
29490		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
29491		, can_use_save_link = "download" in save_link
29492		, click = function(node) {
29493			var event = new MouseEvent("click");
29494			node.dispatchEvent(event);
29495		}
29496		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
29497		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
29498		, throw_outside = function(ex) {
29499			(view.setImmediate || view.setTimeout)(function() {
29500				throw ex;
29501			}, 0);
29502		}
29503		, force_saveable_type = "application/octet-stream"
29504		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
29505		, arbitrary_revoke_timeout = 1000 * 40 // in ms
29506		, revoke = function(file) {
29507			var revoker = function() {
29508				if (typeof file === "string") { // file is an object URL
29509					get_URL().revokeObjectURL(file);
29510				} else { // file is a File
29511					file.remove();
29512				}
29513			};
29514			setTimeout(revoker, arbitrary_revoke_timeout);
29515		}
29516		, dispatch = function(filesaver, event_types, event) {
29517			event_types = [].concat(event_types);
29518			var i = event_types.length;
29519			while (i--) {
29520				var listener = filesaver["on" + event_types[i]];
29521				if (typeof listener === "function") {
29522					try {
29523						listener.call(filesaver, event || filesaver);
29524					} catch (ex) {
29525						throw_outside(ex);
29526					}
29527				}
29528			}
29529		}
29530		, auto_bom = function(blob) {
29531			// prepend BOM for UTF-8 XML and text/* types (including HTML)
29532			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
29533			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
29534				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
29535			}
29536			return blob;
29537		}
29538		, FileSaver = function(blob, name, no_auto_bom) {
29539			if (!no_auto_bom) {
29540				blob = auto_bom(blob);
29541			}
29542			// First try a.download, then web filesystem, then object URLs
29543			var
29544				  filesaver = this
29545				, type = blob.type
29546				, force = type === force_saveable_type
29547				, object_url
29548				, dispatch_all = function() {
29549					dispatch(filesaver, "writestart progress write writeend".split(" "));
29550				}
29551				// on any filesys errors revert to saving with object URLs
29552				, fs_error = function() {
29553					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
29554						// Safari doesn't allow downloading of blob urls
29555						var reader = new FileReader();
29556						reader.onloadend = function() {
29557							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
29558							var popup = view.open(url, '_blank');
29559							if(!popup) view.location.href = url;
29560							url=undefined; // release reference before dispatching
29561							filesaver.readyState = filesaver.DONE;
29562							dispatch_all();
29563						};
29564						reader.readAsDataURL(blob);
29565						filesaver.readyState = filesaver.INIT;
29566						return;
29567					}
29568					// don't create more object URLs than needed
29569					if (!object_url) {
29570						object_url = get_URL().createObjectURL(blob);
29571					}
29572					if (force) {
29573						view.location.href = object_url;
29574					} else {
29575						var opened = view.open(object_url, "_blank");
29576						if (!opened) {
29577							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
29578							view.location.href = object_url;
29579						}
29580					}
29581					filesaver.readyState = filesaver.DONE;
29582					dispatch_all();
29583					revoke(object_url);
29584				}
29585			;
29586			filesaver.readyState = filesaver.INIT;
29587
29588			if (can_use_save_link) {
29589				object_url = get_URL().createObjectURL(blob);
29590				setTimeout(function() {
29591					save_link.href = object_url;
29592					save_link.download = name;
29593					click(save_link);
29594					dispatch_all();
29595					revoke(object_url);
29596					filesaver.readyState = filesaver.DONE;
29597				});
29598				return;
29599			}
29600
29601			fs_error();
29602		}
29603		, FS_proto = FileSaver.prototype
29604		, saveAs = function(blob, name, no_auto_bom) {
29605			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
29606		}
29607	;
29608	// IE 10+ (native saveAs)
29609	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
29610		return function(blob, name, no_auto_bom) {
29611			name = name || blob.name || "download";
29612
29613			if (!no_auto_bom) {
29614				blob = auto_bom(blob);
29615			}
29616			return navigator.msSaveOrOpenBlob(blob, name);
29617		};
29618	}
29619
29620	FS_proto.abort = function(){};
29621	FS_proto.readyState = FS_proto.INIT = 0;
29622	FS_proto.WRITING = 1;
29623	FS_proto.DONE = 2;
29624
29625	FS_proto.error =
29626	FS_proto.onwritestart =
29627	FS_proto.onprogress =
29628	FS_proto.onwrite =
29629	FS_proto.onabort =
29630	FS_proto.onerror =
29631	FS_proto.onwriteend =
29632		null;
29633
29634	return saveAs;
29635}(
29636	   typeof self !== "undefined" && self
29637	|| typeof window !== "undefined" && window
29638	|| this.content
29639));
29640
29641
29642// Expose file saver on the DataTables API. Can't attach to `DataTables.Buttons`
29643// since this file can be loaded before Button's core!
29644DataTable.fileSave = _saveAs;
29645
29646
29647/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
29648 * Local (private) functions
29649 */
29650
29651/**
29652 * Get the sheet name for Excel exports.
29653 *
29654 * @param {object}	config Button configuration
29655 */
29656var _sheetname = function ( config )
29657{
29658	var sheetName = 'Sheet1';
29659
29660	if ( config.sheetName ) {
29661		sheetName = config.sheetName.replace(/[\[\]\*\/\\\?\:]/g, '');
29662	}
29663
29664	return sheetName;
29665};
29666
29667/**
29668 * Get the newline character(s)
29669 *
29670 * @param {object}	config Button configuration
29671 * @return {string}				Newline character
29672 */
29673var _newLine = function ( config )
29674{
29675	return config.newline ?
29676		config.newline :
29677		navigator.userAgent.match(/Windows/) ?
29678			'\r\n' :
29679			'\n';
29680};
29681
29682/**
29683 * Combine the data from the `buttons.exportData` method into a string that
29684 * will be used in the export file.
29685 *
29686 * @param	{DataTable.Api} dt		 DataTables API instance
29687 * @param	{object}				config Button configuration
29688 * @return {object}							 The data to export
29689 */
29690var _exportData = function ( dt, config )
29691{
29692	var newLine = _newLine( config );
29693	var data = dt.buttons.exportData( config.exportOptions );
29694	var boundary = config.fieldBoundary;
29695	var separator = config.fieldSeparator;
29696	var reBoundary = new RegExp( boundary, 'g' );
29697	var escapeChar = config.escapeChar !== undefined ?
29698		config.escapeChar :
29699		'\\';
29700	var join = function ( a ) {
29701		var s = '';
29702
29703		// If there is a field boundary, then we might need to escape it in
29704		// the source data
29705		for ( var i=0, ien=a.length ; i<ien ; i++ ) {
29706			if ( i > 0 ) {
29707				s += separator;
29708			}
29709
29710			s += boundary ?
29711				boundary + ('' + a[i]).replace( reBoundary, escapeChar+boundary ) + boundary :
29712				a[i];
29713		}
29714
29715		return s;
29716	};
29717
29718	var header = config.header ? join( data.header )+newLine : '';
29719	var footer = config.footer && data.footer ? newLine+join( data.footer ) : '';
29720	var body = [];
29721
29722	for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
29723		body.push( join( data.body[i] ) );
29724	}
29725
29726	return {
29727		str: header + body.join( newLine ) + footer,
29728		rows: body.length
29729	};
29730};
29731
29732/**
29733 * Older versions of Safari (prior to tech preview 18) don't support the
29734 * download option required.
29735 *
29736 * @return {Boolean} `true` if old Safari
29737 */
29738var _isDuffSafari = function ()
29739{
29740	var safari = navigator.userAgent.indexOf('Safari') !== -1 &&
29741		navigator.userAgent.indexOf('Chrome') === -1 &&
29742		navigator.userAgent.indexOf('Opera') === -1;
29743
29744	if ( ! safari ) {
29745		return false;
29746	}
29747
29748	var version = navigator.userAgent.match( /AppleWebKit\/(\d+\.\d+)/ );
29749	if ( version && version.length > 1 && version[1]*1 < 603.1 ) {
29750		return true;
29751	}
29752
29753	return false;
29754};
29755
29756/**
29757 * Convert from numeric position to letter for column names in Excel
29758 * @param  {int} n Column number
29759 * @return {string} Column letter(s) name
29760 */
29761function createCellPos( n ){
29762	var ordA = 'A'.charCodeAt(0);
29763	var ordZ = 'Z'.charCodeAt(0);
29764	var len = ordZ - ordA + 1;
29765	var s = "";
29766
29767	while( n >= 0 ) {
29768		s = String.fromCharCode(n % len + ordA) + s;
29769		n = Math.floor(n / len) - 1;
29770	}
29771
29772	return s;
29773}
29774
29775try {
29776	var _serialiser = new XMLSerializer();
29777	var _ieExcel;
29778}
29779catch (t) {}
29780
29781/**
29782 * Recursively add XML files from an object's structure to a ZIP file. This
29783 * allows the XSLX file to be easily defined with an object's structure matching
29784 * the files structure.
29785 *
29786 * @param {JSZip} zip ZIP package
29787 * @param {object} obj Object to add (recursive)
29788 */
29789function _addToZip( zip, obj ) {
29790	if ( _ieExcel === undefined ) {
29791		// Detect if we are dealing with IE's _awful_ serialiser by seeing if it
29792		// drop attributes
29793		_ieExcel = _serialiser
29794			.serializeToString(
29795				( new window.DOMParser() ).parseFromString( excelStrings['xl/worksheets/sheet1.xml'], 'text/xml' )
29796			)
29797			.indexOf( 'xmlns:r' ) === -1;
29798	}
29799
29800	$.each( obj, function ( name, val ) {
29801		if ( $.isPlainObject( val ) ) {
29802			var newDir = zip.folder( name );
29803			_addToZip( newDir, val );
29804		}
29805		else {
29806			if ( _ieExcel ) {
29807				// IE's XML serialiser will drop some name space attributes from
29808				// from the root node, so we need to save them. Do this by
29809				// replacing the namespace nodes with a regular attribute that
29810				// we convert back when serialised. Edge does not have this
29811				// issue
29812				var worksheet = val.childNodes[0];
29813				var i, ien;
29814				var attrs = [];
29815
29816				for ( i=worksheet.attributes.length-1 ; i>=0 ; i-- ) {
29817					var attrName = worksheet.attributes[i].nodeName;
29818					var attrValue = worksheet.attributes[i].nodeValue;
29819
29820					if ( attrName.indexOf( ':' ) !== -1 ) {
29821						attrs.push( { name: attrName, value: attrValue } );
29822
29823						worksheet.removeAttribute( attrName );
29824					}
29825				}
29826
29827				for ( i=0, ien=attrs.length ; i<ien ; i++ ) {
29828					var attr = val.createAttribute( attrs[i].name.replace( ':', '_dt_b_namespace_token_' ) );
29829					attr.value = attrs[i].value;
29830					worksheet.setAttributeNode( attr );
29831				}
29832			}
29833
29834			var str = _serialiser.serializeToString(val);
29835
29836			// Fix IE's XML
29837			if ( _ieExcel ) {
29838				// IE doesn't include the XML declaration
29839				if ( str.indexOf( '<?xml' ) === -1 ) {
29840					str = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+str;
29841				}
29842
29843				// Return namespace attributes to being as such
29844				str = str.replace( /_dt_b_namespace_token_/g, ':' );
29845
29846				// Remove testing name space that IE puts into the space preserve attr
29847				str = str.replace( /xmlns:NS[\d]+="" NS[\d]+:/g, '' );
29848			}
29849
29850			// Safari, IE and Edge will put empty name space attributes onto
29851			// various elements making them useless. This strips them out
29852			str = str.replace( /<([^<>]*?) xmlns=""([^<>]*?)>/g, '<$1 $2>' );
29853
29854			zip.file( name, str );
29855		}
29856	} );
29857}
29858
29859/**
29860 * Create an XML node and add any children, attributes, etc without needing to
29861 * be verbose in the DOM.
29862 *
29863 * @param  {object} doc      XML document
29864 * @param  {string} nodeName Node name
29865 * @param  {object} opts     Options - can be `attr` (attributes), `children`
29866 *   (child nodes) and `text` (text content)
29867 * @return {node}            Created node
29868 */
29869function _createNode( doc, nodeName, opts ) {
29870	var tempNode = doc.createElement( nodeName );
29871
29872	if ( opts ) {
29873		if ( opts.attr ) {
29874			$(tempNode).attr( opts.attr );
29875		}
29876
29877		if ( opts.children ) {
29878			$.each( opts.children, function ( key, value ) {
29879				tempNode.appendChild( value );
29880			} );
29881		}
29882
29883		if ( opts.text !== null && opts.text !== undefined ) {
29884			tempNode.appendChild( doc.createTextNode( opts.text ) );
29885		}
29886	}
29887
29888	return tempNode;
29889}
29890
29891/**
29892 * Get the width for an Excel column based on the contents of that column
29893 * @param  {object} data Data for export
29894 * @param  {int}    col  Column index
29895 * @return {int}         Column width
29896 */
29897function _excelColWidth( data, col ) {
29898	var max = data.header[col].length;
29899	var len, lineSplit, str;
29900
29901	if ( data.footer && data.footer[col].length > max ) {
29902		max = data.footer[col].length;
29903	}
29904
29905	for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
29906		var point = data.body[i][col];
29907		str = point !== null && point !== undefined ?
29908			point.toString() :
29909			'';
29910
29911		// If there is a newline character, workout the width of the column
29912		// based on the longest line in the string
29913		if ( str.indexOf('\n') !== -1 ) {
29914			lineSplit = str.split('\n');
29915			lineSplit.sort( function (a, b) {
29916				return b.length - a.length;
29917			} );
29918
29919			len = lineSplit[0].length;
29920		}
29921		else {
29922			len = str.length;
29923		}
29924
29925		if ( len > max ) {
29926			max = len;
29927		}
29928
29929		// Max width rather than having potentially massive column widths
29930		if ( max > 40 ) {
29931			return 54; // 40 * 1.35
29932		}
29933	}
29934
29935	max *= 1.35;
29936
29937	// And a min width
29938	return max > 6 ? max : 6;
29939}
29940
29941// Excel - Pre-defined strings to build a basic XLSX file
29942var excelStrings = {
29943	"_rels/.rels":
29944		'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
29945		'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'+
29946			'<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>'+
29947		'</Relationships>',
29948
29949	"xl/_rels/workbook.xml.rels":
29950		'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
29951		'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'+
29952			'<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>'+
29953			'<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>'+
29954		'</Relationships>',
29955
29956	"[Content_Types].xml":
29957		'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
29958		'<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'+
29959			'<Default Extension="xml" ContentType="application/xml" />'+
29960			'<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />'+
29961			'<Default Extension="jpeg" ContentType="image/jpeg" />'+
29962			'<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />'+
29963			'<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />'+
29964			'<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />'+
29965		'</Types>',
29966
29967	"xl/workbook.xml":
29968		'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
29969		'<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">'+
29970			'<fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="24816"/>'+
29971			'<workbookPr showInkAnnotation="0" autoCompressPictures="0"/>'+
29972			'<bookViews>'+
29973				'<workbookView xWindow="0" yWindow="0" windowWidth="25600" windowHeight="19020" tabRatio="500"/>'+
29974			'</bookViews>'+
29975			'<sheets>'+
29976				'<sheet name="Sheet1" sheetId="1" r:id="rId1"/>'+
29977			'</sheets>'+
29978			'<definedNames/>'+
29979		'</workbook>',
29980
29981	"xl/worksheets/sheet1.xml":
29982		'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
29983		'<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+
29984			'<sheetData/>'+
29985			'<mergeCells count="0"/>'+
29986		'</worksheet>',
29987
29988	"xl/styles.xml":
29989		'<?xml version="1.0" encoding="UTF-8"?>'+
29990		'<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+
29991			'<numFmts count="6">'+
29992				'<numFmt numFmtId="164" formatCode="#,##0.00_-\ [$$-45C]"/>'+
29993				'<numFmt numFmtId="165" formatCode="&quot;£&quot;#,##0.00"/>'+
29994				'<numFmt numFmtId="166" formatCode="[$€-2]\ #,##0.00"/>'+
29995				'<numFmt numFmtId="167" formatCode="0.0%"/>'+
29996				'<numFmt numFmtId="168" formatCode="#,##0;(#,##0)"/>'+
29997				'<numFmt numFmtId="169" formatCode="#,##0.00;(#,##0.00)"/>'+
29998			'</numFmts>'+
29999			'<fonts count="5" x14ac:knownFonts="1">'+
30000				'<font>'+
30001					'<sz val="11" />'+
30002					'<name val="Calibri" />'+
30003				'</font>'+
30004				'<font>'+
30005					'<sz val="11" />'+
30006					'<name val="Calibri" />'+
30007					'<color rgb="FFFFFFFF" />'+
30008				'</font>'+
30009				'<font>'+
30010					'<sz val="11" />'+
30011					'<name val="Calibri" />'+
30012					'<b />'+
30013				'</font>'+
30014				'<font>'+
30015					'<sz val="11" />'+
30016					'<name val="Calibri" />'+
30017					'<i />'+
30018				'</font>'+
30019				'<font>'+
30020					'<sz val="11" />'+
30021					'<name val="Calibri" />'+
30022					'<u />'+
30023				'</font>'+
30024			'</fonts>'+
30025			'<fills count="6">'+
30026				'<fill>'+
30027					'<patternFill patternType="none" />'+
30028				'</fill>'+
30029				'<fill>'+ // Excel appears to use this as a dotted background regardless of values but
30030					'<patternFill patternType="none" />'+ // to be valid to the schema, use a patternFill
30031				'</fill>'+
30032				'<fill>'+
30033					'<patternFill patternType="solid">'+
30034						'<fgColor rgb="FFD9D9D9" />'+
30035						'<bgColor indexed="64" />'+
30036					'</patternFill>'+
30037				'</fill>'+
30038				'<fill>'+
30039					'<patternFill patternType="solid">'+
30040						'<fgColor rgb="FFD99795" />'+
30041						'<bgColor indexed="64" />'+
30042					'</patternFill>'+
30043				'</fill>'+
30044				'<fill>'+
30045					'<patternFill patternType="solid">'+
30046						'<fgColor rgb="ffc6efce" />'+
30047						'<bgColor indexed="64" />'+
30048					'</patternFill>'+
30049				'</fill>'+
30050				'<fill>'+
30051					'<patternFill patternType="solid">'+
30052						'<fgColor rgb="ffc6cfef" />'+
30053						'<bgColor indexed="64" />'+
30054					'</patternFill>'+
30055				'</fill>'+
30056			'</fills>'+
30057			'<borders count="2">'+
30058				'<border>'+
30059					'<left />'+
30060					'<right />'+
30061					'<top />'+
30062					'<bottom />'+
30063					'<diagonal />'+
30064				'</border>'+
30065				'<border diagonalUp="false" diagonalDown="false">'+
30066					'<left style="thin">'+
30067						'<color auto="1" />'+
30068					'</left>'+
30069					'<right style="thin">'+
30070						'<color auto="1" />'+
30071					'</right>'+
30072					'<top style="thin">'+
30073						'<color auto="1" />'+
30074					'</top>'+
30075					'<bottom style="thin">'+
30076						'<color auto="1" />'+
30077					'</bottom>'+
30078					'<diagonal />'+
30079				'</border>'+
30080			'</borders>'+
30081			'<cellStyleXfs count="1">'+
30082				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" />'+
30083			'</cellStyleXfs>'+
30084			'<cellXfs count="68">'+
30085				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30086				'<xf numFmtId="0" fontId="1" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30087				'<xf numFmtId="0" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30088				'<xf numFmtId="0" fontId="3" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30089				'<xf numFmtId="0" fontId="4" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30090				'<xf numFmtId="0" fontId="0" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30091				'<xf numFmtId="0" fontId="1" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30092				'<xf numFmtId="0" fontId="2" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30093				'<xf numFmtId="0" fontId="3" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30094				'<xf numFmtId="0" fontId="4" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30095				'<xf numFmtId="0" fontId="0" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30096				'<xf numFmtId="0" fontId="1" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30097				'<xf numFmtId="0" fontId="2" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30098				'<xf numFmtId="0" fontId="3" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30099				'<xf numFmtId="0" fontId="4" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30100				'<xf numFmtId="0" fontId="0" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30101				'<xf numFmtId="0" fontId="1" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30102				'<xf numFmtId="0" fontId="2" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30103				'<xf numFmtId="0" fontId="3" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30104				'<xf numFmtId="0" fontId="4" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30105				'<xf numFmtId="0" fontId="0" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30106				'<xf numFmtId="0" fontId="1" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30107				'<xf numFmtId="0" fontId="2" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30108				'<xf numFmtId="0" fontId="3" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30109				'<xf numFmtId="0" fontId="4" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+
30110				'<xf numFmtId="0" fontId="0" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30111				'<xf numFmtId="0" fontId="1" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30112				'<xf numFmtId="0" fontId="2" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30113				'<xf numFmtId="0" fontId="3" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30114				'<xf numFmtId="0" fontId="4" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30115				'<xf numFmtId="0" fontId="0" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30116				'<xf numFmtId="0" fontId="1" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30117				'<xf numFmtId="0" fontId="2" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30118				'<xf numFmtId="0" fontId="3" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30119				'<xf numFmtId="0" fontId="4" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30120				'<xf numFmtId="0" fontId="0" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30121				'<xf numFmtId="0" fontId="1" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30122				'<xf numFmtId="0" fontId="2" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30123				'<xf numFmtId="0" fontId="3" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30124				'<xf numFmtId="0" fontId="4" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30125				'<xf numFmtId="0" fontId="0" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30126				'<xf numFmtId="0" fontId="1" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30127				'<xf numFmtId="0" fontId="2" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30128				'<xf numFmtId="0" fontId="3" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30129				'<xf numFmtId="0" fontId="4" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30130				'<xf numFmtId="0" fontId="0" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30131				'<xf numFmtId="0" fontId="1" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30132				'<xf numFmtId="0" fontId="2" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30133				'<xf numFmtId="0" fontId="3" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30134				'<xf numFmtId="0" fontId="4" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+
30135				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
30136					'<alignment horizontal="left"/>'+
30137				'</xf>'+
30138				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
30139					'<alignment horizontal="center"/>'+
30140				'</xf>'+
30141				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
30142					'<alignment horizontal="right"/>'+
30143				'</xf>'+
30144				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
30145					'<alignment horizontal="fill"/>'+
30146				'</xf>'+
30147				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
30148					'<alignment textRotation="90"/>'+
30149				'</xf>'+
30150				'<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+
30151					'<alignment wrapText="1"/>'+
30152				'</xf>'+
30153				'<xf numFmtId="9"   fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30154				'<xf numFmtId="164" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30155				'<xf numFmtId="165" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30156				'<xf numFmtId="166" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30157				'<xf numFmtId="167" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30158				'<xf numFmtId="168" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30159				'<xf numFmtId="169" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30160				'<xf numFmtId="3" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30161				'<xf numFmtId="4" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30162				'<xf numFmtId="1" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30163				'<xf numFmtId="2" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30164				'<xf numFmtId="14" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+
30165			'</cellXfs>'+
30166			'<cellStyles count="1">'+
30167				'<cellStyle name="Normal" xfId="0" builtinId="0" />'+
30168			'</cellStyles>'+
30169			'<dxfs count="0" />'+
30170			'<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4" />'+
30171		'</styleSheet>'
30172};
30173// Note we could use 3 `for` loops for the styles, but when gzipped there is
30174// virtually no difference in size, since the above can be easily compressed
30175
30176// Pattern matching for special number formats. Perhaps this should be exposed
30177// via an API in future?
30178// Ref: section 3.8.30 - built in formatters in open spreadsheet
30179//   https://www.ecma-international.org/news/TC45_current_work/Office%20Open%20XML%20Part%204%20-%20Markup%20Language%20Reference.pdf
30180var _excelSpecials = [
30181	{ match: /^\-?\d+\.\d%$/,               style: 60, fmt: function (d) { return d/100; } }, // Precent with d.p.
30182	{ match: /^\-?\d+\.?\d*%$/,             style: 56, fmt: function (d) { return d/100; } }, // Percent
30183	{ match: /^\-?\$[\d,]+.?\d*$/,          style: 57 }, // Dollars
30184	{ match: /^\-?£[\d,]+.?\d*$/,           style: 58 }, // Pounds
30185	{ match: /^\-?€[\d,]+.?\d*$/,           style: 59 }, // Euros
30186	{ match: /^\-?\d+$/,                    style: 65 }, // Numbers without thousand separators
30187	{ match: /^\-?\d+\.\d{2}$/,             style: 66 }, // Numbers 2 d.p. without thousands separators
30188	{ match: /^\([\d,]+\)$/,                style: 61, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } },  // Negative numbers indicated by brackets
30189	{ match: /^\([\d,]+\.\d{2}\)$/,         style: 62, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } },  // Negative numbers indicated by brackets - 2d.p.
30190	{ match: /^\-?[\d,]+$/,                 style: 63 }, // Numbers with thousand separators
30191	{ match: /^\-?[\d,]+\.\d{2}$/,          style: 64 },
30192	{ match: /^[\d]{4}\-[\d]{2}\-[\d]{2}$/, style: 67, fmt: function (d) {return Math.round(25569 + (Date.parse(d) / (86400 * 1000)));}} //Date yyyy-mm-dd
30193];
30194
30195
30196
30197/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
30198 * Buttons
30199 */
30200
30201//
30202// Copy to clipboard
30203//
30204DataTable.ext.buttons.copyHtml5 = {
30205	className: 'buttons-copy buttons-html5',
30206
30207	text: function ( dt ) {
30208		return dt.i18n( 'buttons.copy', 'Copy' );
30209	},
30210
30211	action: function ( e, dt, button, config ) {
30212		this.processing( true );
30213
30214		var that = this;
30215		var exportData = _exportData( dt, config );
30216		var info = dt.buttons.exportInfo( config );
30217		var newline = _newLine(config);
30218		var output = exportData.str;
30219		var hiddenDiv = $('<div/>')
30220			.css( {
30221				height: 1,
30222				width: 1,
30223				overflow: 'hidden',
30224				position: 'fixed',
30225				top: 0,
30226				left: 0
30227			} );
30228
30229		if ( info.title ) {
30230			output = info.title + newline + newline + output;
30231		}
30232
30233		if ( info.messageTop ) {
30234			output = info.messageTop + newline + newline + output;
30235		}
30236
30237		if ( info.messageBottom ) {
30238			output = output + newline + newline + info.messageBottom;
30239		}
30240
30241		if ( config.customize ) {
30242			output = config.customize( output, config, dt );
30243		}
30244
30245		var textarea = $('<textarea readonly/>')
30246			.val( output )
30247			.appendTo( hiddenDiv );
30248
30249		// For browsers that support the copy execCommand, try to use it
30250		if ( document.queryCommandSupported('copy') ) {
30251			hiddenDiv.appendTo( dt.table().container() );
30252			textarea[0].focus();
30253			textarea[0].select();
30254
30255			try {
30256				var successful = document.execCommand( 'copy' );
30257				hiddenDiv.remove();
30258
30259				if (successful) {
30260					dt.buttons.info(
30261						dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ),
30262						dt.i18n( 'buttons.copySuccess', {
30263							1: 'Copied one row to clipboard',
30264							_: 'Copied %d rows to clipboard'
30265						}, exportData.rows ),
30266						2000
30267					);
30268
30269					this.processing( false );
30270					return;
30271				}
30272			}
30273			catch (t) {}
30274		}
30275
30276		// Otherwise we show the text box and instruct the user to use it
30277		var message = $('<span>'+dt.i18n( 'buttons.copyKeys',
30278				'Press <i>ctrl</i> or <i>\u2318</i> + <i>C</i> to copy the table data<br>to your system clipboard.<br><br>'+
30279				'To cancel, click this message or press escape.' )+'</span>'
30280			)
30281			.append( hiddenDiv );
30282
30283		dt.buttons.info( dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ), message, 0 );
30284
30285		// Select the text so when the user activates their system clipboard
30286		// it will copy that text
30287		textarea[0].focus();
30288		textarea[0].select();
30289
30290		// Event to hide the message when the user is done
30291		var container = $(message).closest('.dt-button-info');
30292		var close = function () {
30293			container.off( 'click.buttons-copy' );
30294			$(document).off( '.buttons-copy' );
30295			dt.buttons.info( false );
30296		};
30297
30298		container.on( 'click.buttons-copy', close );
30299		$(document)
30300			.on( 'keydown.buttons-copy', function (e) {
30301				if ( e.keyCode === 27 ) { // esc
30302					close();
30303					that.processing( false );
30304				}
30305			} )
30306			.on( 'copy.buttons-copy cut.buttons-copy', function () {
30307				close();
30308				that.processing( false );
30309			} );
30310	},
30311
30312	exportOptions: {},
30313
30314	fieldSeparator: '\t',
30315
30316	fieldBoundary: '',
30317
30318	header: true,
30319
30320	footer: false,
30321
30322	title: '*',
30323
30324	messageTop: '*',
30325
30326	messageBottom: '*'
30327};
30328
30329//
30330// CSV export
30331//
30332DataTable.ext.buttons.csvHtml5 = {
30333	bom: false,
30334
30335	className: 'buttons-csv buttons-html5',
30336
30337	available: function () {
30338		return window.FileReader !== undefined && window.Blob;
30339	},
30340
30341	text: function ( dt ) {
30342		return dt.i18n( 'buttons.csv', 'CSV' );
30343	},
30344
30345	action: function ( e, dt, button, config ) {
30346		this.processing( true );
30347
30348		// Set the text
30349		var output = _exportData( dt, config ).str;
30350		var info = dt.buttons.exportInfo(config);
30351		var charset = config.charset;
30352
30353		if ( config.customize ) {
30354			output = config.customize( output, config, dt );
30355		}
30356
30357		if ( charset !== false ) {
30358			if ( ! charset ) {
30359				charset = document.characterSet || document.charset;
30360			}
30361
30362			if ( charset ) {
30363				charset = ';charset='+charset;
30364			}
30365		}
30366		else {
30367			charset = '';
30368		}
30369
30370		if ( config.bom ) {
30371			output = String.fromCharCode(0xFEFF) + output;
30372		}
30373
30374		_saveAs(
30375			new Blob( [output], {type: 'text/csv'+charset} ),
30376			info.filename,
30377			true
30378		);
30379
30380		this.processing( false );
30381	},
30382
30383	filename: '*',
30384
30385	extension: '.csv',
30386
30387	exportOptions: {},
30388
30389	fieldSeparator: ',',
30390
30391	fieldBoundary: '"',
30392
30393	escapeChar: '"',
30394
30395	charset: null,
30396
30397	header: true,
30398
30399	footer: false
30400};
30401
30402//
30403// Excel (xlsx) export
30404//
30405DataTable.ext.buttons.excelHtml5 = {
30406	className: 'buttons-excel buttons-html5',
30407
30408	available: function () {
30409		return window.FileReader !== undefined && _jsZip() !== undefined && ! _isDuffSafari() && _serialiser;
30410	},
30411
30412	text: function ( dt ) {
30413		return dt.i18n( 'buttons.excel', 'Excel' );
30414	},
30415
30416	action: function ( e, dt, button, config ) {
30417		this.processing( true );
30418
30419		var that = this;
30420		var rowPos = 0;
30421		var dataStartRow, dataEndRow;
30422		var getXml = function ( type ) {
30423			var str = excelStrings[ type ];
30424
30425			//str = str.replace( /xmlns:/g, 'xmlns_' ).replace( /mc:/g, 'mc_' );
30426
30427			return $.parseXML( str );
30428		};
30429		var rels = getXml('xl/worksheets/sheet1.xml');
30430		var relsGet = rels.getElementsByTagName( "sheetData" )[0];
30431
30432		var xlsx = {
30433			_rels: {
30434				".rels": getXml('_rels/.rels')
30435			},
30436			xl: {
30437				_rels: {
30438					"workbook.xml.rels": getXml('xl/_rels/workbook.xml.rels')
30439				},
30440				"workbook.xml": getXml('xl/workbook.xml'),
30441				"styles.xml": getXml('xl/styles.xml'),
30442				"worksheets": {
30443					"sheet1.xml": rels
30444				}
30445
30446			},
30447			"[Content_Types].xml": getXml('[Content_Types].xml')
30448		};
30449
30450		var data = dt.buttons.exportData( config.exportOptions );
30451		var currentRow, rowNode;
30452		var addRow = function ( row ) {
30453			currentRow = rowPos+1;
30454			rowNode = _createNode( rels, "row", { attr: {r:currentRow} } );
30455
30456			for ( var i=0, ien=row.length ; i<ien ; i++ ) {
30457				// Concat both the Cell Columns as a letter and the Row of the cell.
30458				var cellId = createCellPos(i) + '' + currentRow;
30459				var cell = null;
30460
30461				// For null, undefined of blank cell, continue so it doesn't create the _createNode
30462				if ( row[i] === null || row[i] === undefined || row[i] === '' ) {
30463					if ( config.createEmptyCells === true ) {
30464						row[i] = '';
30465					}
30466					else {
30467						continue;
30468					}
30469				}
30470
30471				var originalContent = row[i];
30472				row[i] = typeof row[i].trim === 'function'
30473					? row[i].trim()
30474					: row[i];
30475
30476				// Special number formatting options
30477				for ( var j=0, jen=_excelSpecials.length ; j<jen ; j++ ) {
30478					var special = _excelSpecials[j];
30479
30480					// TODO Need to provide the ability for the specials to say
30481					// if they are returning a string, since at the moment it is
30482					// assumed to be a number
30483					if ( row[i].match && ! row[i].match(/^0\d+/) && row[i].match( special.match ) ) {
30484						var val = row[i].replace(/[^\d\.\-]/g, '');
30485
30486						if ( special.fmt ) {
30487							val = special.fmt( val );
30488						}
30489
30490						cell = _createNode( rels, 'c', {
30491							attr: {
30492								r: cellId,
30493								s: special.style
30494							},
30495							children: [
30496								_createNode( rels, 'v', { text: val } )
30497							]
30498						} );
30499
30500						break;
30501					}
30502				}
30503
30504				if ( ! cell ) {
30505					if ( typeof row[i] === 'number' || (
30506						row[i].match &&
30507						row[i].match(/^-?\d+(\.\d+)?$/) &&
30508						! row[i].match(/^0\d+/) )
30509					) {
30510						// Detect numbers - don't match numbers with leading zeros
30511						// or a negative anywhere but the start
30512						cell = _createNode( rels, 'c', {
30513							attr: {
30514								t: 'n',
30515								r: cellId
30516							},
30517							children: [
30518								_createNode( rels, 'v', { text: row[i] } )
30519							]
30520						} );
30521					}
30522					else {
30523						// String output - replace non standard characters for text output
30524						var text = ! originalContent.replace ?
30525							originalContent :
30526							originalContent.replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, '');
30527
30528						cell = _createNode( rels, 'c', {
30529							attr: {
30530								t: 'inlineStr',
30531								r: cellId
30532							},
30533							children:{
30534								row: _createNode( rels, 'is', {
30535									children: {
30536										row: _createNode( rels, 't', {
30537											text: text,
30538											attr: {
30539												'xml:space': 'preserve'
30540											}
30541										} )
30542									}
30543								} )
30544							}
30545						} );
30546					}
30547				}
30548
30549				rowNode.appendChild( cell );
30550			}
30551
30552			relsGet.appendChild(rowNode);
30553			rowPos++;
30554		};
30555
30556		if ( config.customizeData ) {
30557			config.customizeData( data );
30558		}
30559
30560		var mergeCells = function ( row, colspan ) {
30561			var mergeCells = $('mergeCells', rels);
30562
30563			mergeCells[0].appendChild( _createNode( rels, 'mergeCell', {
30564				attr: {
30565					ref: 'A'+row+':'+createCellPos(colspan)+row
30566				}
30567			} ) );
30568			mergeCells.attr( 'count', parseFloat(mergeCells.attr( 'count' ))+1 );
30569			$('row:eq('+(row-1)+') c', rels).attr( 's', '51' ); // centre
30570		};
30571
30572		// Title and top messages
30573		var exportInfo = dt.buttons.exportInfo( config );
30574		if ( exportInfo.title ) {
30575			addRow( [exportInfo.title], rowPos );
30576			mergeCells( rowPos, data.header.length-1 );
30577		}
30578
30579		if ( exportInfo.messageTop ) {
30580			addRow( [exportInfo.messageTop], rowPos );
30581			mergeCells( rowPos, data.header.length-1 );
30582		}
30583
30584
30585		// Table itself
30586		if ( config.header ) {
30587			addRow( data.header, rowPos );
30588			$('row:last c', rels).attr( 's', '2' ); // bold
30589		}
30590	
30591		dataStartRow = rowPos;
30592
30593		for ( var n=0, ie=data.body.length ; n<ie ; n++ ) {
30594			addRow( data.body[n], rowPos );
30595		}
30596	
30597		dataEndRow = rowPos;
30598
30599		if ( config.footer && data.footer ) {
30600			addRow( data.footer, rowPos);
30601			$('row:last c', rels).attr( 's', '2' ); // bold
30602		}
30603
30604		// Below the table
30605		if ( exportInfo.messageBottom ) {
30606			addRow( [exportInfo.messageBottom], rowPos );
30607			mergeCells( rowPos, data.header.length-1 );
30608		}
30609
30610		// Set column widths
30611		var cols = _createNode( rels, 'cols' );
30612		$('worksheet', rels).prepend( cols );
30613
30614		for ( var i=0, ien=data.header.length ; i<ien ; i++ ) {
30615			cols.appendChild( _createNode( rels, 'col', {
30616				attr: {
30617					min: i+1,
30618					max: i+1,
30619					width: _excelColWidth( data, i ),
30620					customWidth: 1
30621				}
30622			} ) );
30623		}
30624
30625		// Workbook modifications
30626		var workbook = xlsx.xl['workbook.xml'];
30627
30628		$( 'sheets sheet', workbook ).attr( 'name', _sheetname( config ) );
30629
30630		// Auto filter for columns
30631		if ( config.autoFilter ) {
30632			$('mergeCells', rels).before( _createNode( rels, 'autoFilter', {
30633				attr: {
30634					ref: 'A'+dataStartRow+':'+createCellPos(data.header.length-1)+dataEndRow
30635				}
30636			} ) );
30637
30638			$('definedNames', workbook).append( _createNode( workbook, 'definedName', {
30639				attr: {
30640					name: '_xlnm._FilterDatabase',
30641					localSheetId: '0',
30642					hidden: 1
30643				},
30644				text: _sheetname(config)+'!$A$'+dataStartRow+':'+createCellPos(data.header.length-1)+dataEndRow
30645			} ) );
30646		}
30647
30648		// Let the developer customise the document if they want to
30649		if ( config.customize ) {
30650			config.customize( xlsx, config, dt );
30651		}
30652
30653		// Excel doesn't like an empty mergeCells tag
30654		if ( $('mergeCells', rels).children().length === 0 ) {
30655			$('mergeCells', rels).remove();
30656		}
30657
30658		var jszip = _jsZip();
30659		var zip = new jszip();
30660		var zipConfig = {
30661			type: 'blob',
30662			mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
30663		};
30664
30665		_addToZip( zip, xlsx );
30666
30667		if ( zip.generateAsync ) {
30668			// JSZip 3+
30669			zip
30670				.generateAsync( zipConfig )
30671				.then( function ( blob ) {
30672					_saveAs( blob, exportInfo.filename );
30673					that.processing( false );
30674				} );
30675		}
30676		else {
30677			// JSZip 2.5
30678			_saveAs(
30679				zip.generate( zipConfig ),
30680				exportInfo.filename
30681			);
30682			this.processing( false );
30683		}
30684	},
30685
30686	filename: '*',
30687
30688	extension: '.xlsx',
30689
30690	exportOptions: {},
30691
30692	header: true,
30693
30694	footer: false,
30695
30696	title: '*',
30697
30698	messageTop: '*',
30699
30700	messageBottom: '*',
30701
30702	createEmptyCells: false,
30703
30704	autoFilter: false,
30705
30706	sheetName: ''
30707};
30708
30709//
30710// PDF export - using pdfMake - http://pdfmake.org
30711//
30712DataTable.ext.buttons.pdfHtml5 = {
30713	className: 'buttons-pdf buttons-html5',
30714
30715	available: function () {
30716		return window.FileReader !== undefined && _pdfMake();
30717	},
30718
30719	text: function ( dt ) {
30720		return dt.i18n( 'buttons.pdf', 'PDF' );
30721	},
30722
30723	action: function ( e, dt, button, config ) {
30724		this.processing( true );
30725
30726		var that = this;
30727		var data = dt.buttons.exportData( config.exportOptions );
30728		var info = dt.buttons.exportInfo( config );
30729		var rows = [];
30730
30731		if ( config.header ) {
30732			rows.push( $.map( data.header, function ( d ) {
30733				return {
30734					text: typeof d === 'string' ? d : d+'',
30735					style: 'tableHeader'
30736				};
30737			} ) );
30738		}
30739
30740		for ( var i=0, ien=data.body.length ; i<ien ; i++ ) {
30741			rows.push( $.map( data.body[i], function ( d ) {
30742				if ( d === null || d === undefined ) {
30743					d = '';
30744				}
30745				return {
30746					text: typeof d === 'string' ? d : d+'',
30747					style: i % 2 ? 'tableBodyEven' : 'tableBodyOdd'
30748				};
30749			} ) );
30750		}
30751
30752		if ( config.footer && data.footer) {
30753			rows.push( $.map( data.footer, function ( d ) {
30754				return {
30755					text: typeof d === 'string' ? d : d+'',
30756					style: 'tableFooter'
30757				};
30758			} ) );
30759		}
30760
30761		var doc = {
30762			pageSize: config.pageSize,
30763			pageOrientation: config.orientation,
30764			content: [
30765				{
30766					table: {
30767						headerRows: 1,
30768						body: rows
30769					},
30770					layout: 'noBorders'
30771				}
30772			],
30773			styles: {
30774				tableHeader: {
30775					bold: true,
30776					fontSize: 11,
30777					color: 'white',
30778					fillColor: '#2d4154',
30779					alignment: 'center'
30780				},
30781				tableBodyEven: {},
30782				tableBodyOdd: {
30783					fillColor: '#f3f3f3'
30784				},
30785				tableFooter: {
30786					bold: true,
30787					fontSize: 11,
30788					color: 'white',
30789					fillColor: '#2d4154'
30790				},
30791				title: {
30792					alignment: 'center',
30793					fontSize: 15
30794				},
30795				message: {}
30796			},
30797			defaultStyle: {
30798				fontSize: 10
30799			}
30800		};
30801
30802		if ( info.messageTop ) {
30803			doc.content.unshift( {
30804				text: info.messageTop,
30805				style: 'message',
30806				margin: [ 0, 0, 0, 12 ]
30807			} );
30808		}
30809
30810		if ( info.messageBottom ) {
30811			doc.content.push( {
30812				text: info.messageBottom,
30813				style: 'message',
30814				margin: [ 0, 0, 0, 12 ]
30815			} );
30816		}
30817
30818		if ( info.title ) {
30819			doc.content.unshift( {
30820				text: info.title,
30821				style: 'title',
30822				margin: [ 0, 0, 0, 12 ]
30823			} );
30824		}
30825
30826		if ( config.customize ) {
30827			config.customize( doc, config, dt );
30828		}
30829
30830		var pdf = _pdfMake().createPdf( doc );
30831
30832		if ( config.download === 'open' && ! _isDuffSafari() ) {
30833			pdf.open();
30834		}
30835		else {
30836			pdf.download( info.filename );
30837		}
30838
30839		this.processing( false );
30840	},
30841
30842	title: '*',
30843
30844	filename: '*',
30845
30846	extension: '.pdf',
30847
30848	exportOptions: {},
30849
30850	orientation: 'portrait',
30851
30852	pageSize: 'A4',
30853
30854	header: true,
30855
30856	footer: false,
30857
30858	messageTop: '*',
30859
30860	messageBottom: '*',
30861
30862	customize: null,
30863
30864	download: 'download'
30865};
30866
30867
30868return DataTable.Buttons;
30869}));
30870
30871
30872/***/ }),
30873/* 13 */
30874/***/ (function(module, exports, __webpack_require__) {
30875
30876var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! DataTables styling wrapper for Responsive
30877 * ©2018 SpryMedia Ltd - datatables.net/license
30878 */
30879
30880(function( factory ){
30881	if ( true ) {
30882		// AMD
30883		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(14), __webpack_require__(15)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {
30884			return factory( $, window, document );
30885		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
30886				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
30887	}
30888	else {}
30889}(function( $, window, document, undefined ) {
30890
30891return $.fn.dataTable;
30892
30893}));
30894
30895/***/ }),
30896/* 14 */
30897/***/ (function(module, exports, __webpack_require__) {
30898
30899var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! DataTables styling integration
30900 * ©2018 SpryMedia Ltd - datatables.net/license
30901 */
30902
30903(function( factory ){
30904	if ( true ) {
30905		// AMD
30906		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {
30907			return factory( $, window, document );
30908		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
30909				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
30910	}
30911	else {}
30912}(function( $, window, document, undefined ) {
30913
30914return $.fn.dataTable;
30915
30916}));
30917
30918
30919/***/ }),
30920/* 15 */
30921/***/ (function(module, exports, __webpack_require__) {
30922
30923var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
30923/*! Responsive 2.2.9
30924 * 2014-2021 SpryMedia Ltd - datatables.net/license
30925 */
30926
30927/**
30928 * @summary     Responsive
30929 * @description Responsive tables plug-in for DataTables
30930 * @version     2.2.9
30931 * @file        dataTables.responsive.js
30932 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
30933 * @contact     www.sprymedia.co.uk/contact
30934 * @copyright   Copyright 2014-2021 SpryMedia Ltd.
30935 *
30936 * This source file is free software, available under the following license:
30937 *   MIT license - http://datatables.net/license/mit
30938 *
30939 * This source file is distributed in the hope that it will be useful, but
30940 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30941 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
30942 *
30943 * For details please refer to: http://www.datatables.net
30944 */
30945(function( factory ){
30946	if ( true ) {
30947		// AMD
30948		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) {
30949			return factory( $, window, document );
30950		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
30951				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
30952	}
30953	else {}
30954}(function( $, window, document, undefined ) {
30955'use strict';
30956var DataTable = $.fn.dataTable;
30957
30958
30959/**
30960 * Responsive is a plug-in for the DataTables library that makes use of
30961 * DataTables' ability to change the visibility of columns, changing the
30962 * visibility of columns so the displayed columns fit into the table container.
30963 * The end result is that complex tables will be dynamically adjusted to fit
30964 * into the viewport, be it on a desktop, tablet or mobile browser.
30965 *
30966 * Responsive for DataTables has two modes of operation, which can used
30967 * individually or combined:
30968 *
30969 * * Class name based control - columns assigned class names that match the
30970 *   breakpoint logic can be shown / hidden as required for each breakpoint.
30971 * * Automatic control - columns are automatically hidden when there is no
30972 *   room left to display them. Columns removed from the right.
30973 *
30974 * In additional to column visibility control, Responsive also has built into
30975 * options to use DataTables' child row display to show / hide the information
30976 * from the table that has been hidden. There are also two modes of operation
30977 * for this child row display:
30978 *
30979 * * Inline - when the control element that the user can use to show / hide
30980 *   child rows is displayed inside the first column of the table.
30981 * * Column - where a whole column is dedicated to be the show / hide control.
30982 *
30983 * Initialisation of Responsive is performed by:
30984 *
30985 * * Adding the class `responsive` or `dt-responsive` to the table. In this case
30986 *   Responsive will automatically be initialised with the default configuration
30987 *   options when the DataTable is created.
30988 * * Using the `responsive` option in the DataTables configuration options. This
30989 *   can also be used to specify the configuration options, or simply set to
30990 *   `true` to use the defaults.
30991 *
30992 *  @class
30993 *  @param {object} settings DataTables settings object for the host table
30994 *  @param {object} [opts] Configuration options
30995 *  @requires jQuery 1.7+
30996 *  @requires DataTables 1.10.3+
30997 *
30998 *  @example
30999 *      $('#example').DataTable( {
31000 *        responsive: true
31001 *      } );
31002 *    } );
31003 */
31004var Responsive = function ( settings, opts ) {
31005	// Sanity check that we are using DataTables 1.10 or newer
31006	if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.10' ) ) {
31007		throw 'DataTables Responsive requires DataTables 1.10.10 or newer';
31008	}
31009
31010	this.s = {
31011		dt: new DataTable.Api( settings ),
31012		columns: [],
31013		current: []
31014	};
31015
31016	// Check if responsive has already been initialised on this table
31017	if ( this.s.dt.settings()[0].responsive ) {
31018		return;
31019	}
31020
31021	// details is an object, but for simplicity the user can give it as a string
31022	// or a boolean
31023	if ( opts && typeof opts.details === 'string' ) {
31024		opts.details = { type: opts.details };
31025	}
31026	else if ( opts && opts.details === false ) {
31027		opts.details = { type: false };
31028	}
31029	else if ( opts && opts.details === true ) {
31030		opts.details = { type: 'inline' };
31031	}
31032
31033	this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
31034	settings.responsive = this;
31035	this._constructor();
31036};
31037
31038$.extend( Responsive.prototype, {
31039	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
31040	 * Constructor
31041	 */
31042
31043	/**
31044	 * Initialise the Responsive instance
31045	 *
31046	 * @private
31047	 */
31048	_constructor: function ()
31049	{
31050		var that = this;
31051		var dt = this.s.dt;
31052		var dtPrivateSettings = dt.settings()[0];
31053		var oldWindowWidth = $(window).innerWidth();
31054
31055		dt.settings()[0]._responsive = this;
31056
31057		// Use DataTables' throttle function to avoid processor thrashing on
31058		// resize
31059		$(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
31060			// iOS has a bug whereby resize can fire when only scrolling
31061			// See: http://stackoverflow.com/questions/8898412
31062			var width = $(window).innerWidth();
31063
31064			if ( width !== oldWindowWidth ) {
31065				that._resize();
31066				oldWindowWidth = width;
31067			}
31068		} ) );
31069
31070		// DataTables doesn't currently trigger an event when a row is added, so
31071		// we need to hook into its private API to enforce the hidden rows when
31072		// new data is added
31073		dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
31074			if ( $.inArray( false, that.s.current ) !== -1 ) {
31075				$('>td, >th', tr).each( function ( i ) {
31076					var idx = dt.column.index( 'toData', i );
31077
31078					if ( that.s.current[idx] === false ) {
31079						$(this).css('display', 'none');
31080					}
31081				} );
31082			}
31083		} );
31084
31085		// Destroy event handler
31086		dt.on( 'destroy.dtr', function () {
31087			dt.off( '.dtr' );
31088			$( dt.table().body() ).off( '.dtr' );
31089			$(window).off( 'resize.dtr orientationchange.dtr' );
31090			dt.cells('.dtr-control').nodes().to$().removeClass('dtr-control');
31091
31092			// Restore the columns that we've hidden
31093			$.each( that.s.current, function ( i, val ) {
31094				if ( val === false ) {
31095					that._setColumnVis( i, true );
31096				}
31097			} );
31098		} );
31099
31100		// Reorder the breakpoints array here in case they have been added out
31101		// of order
31102		this.c.breakpoints.sort( function (a, b) {
31103			return a.width < b.width ? 1 :
31104				a.width > b.width ? -1 : 0;
31105		} );
31106
31107		this._classLogic();
31108		this._resizeAuto();
31109
31110		// Details handler
31111		var details = this.c.details;
31112
31113		if ( details.type !== false ) {
31114			that._detailsInit();
31115
31116			// DataTables will trigger this event on every column it shows and
31117			// hides individually
31118			dt.on( 'column-visibility.dtr', function () {
31119				// Use a small debounce to allow multiple columns to be set together
31120				if ( that._timer ) {
31121					clearTimeout( that._timer );
31122				}
31123
31124				that._timer = setTimeout( function () {
31125					that._timer = null;
31126
31127					that._classLogic();
31128					that._resizeAuto();
31129					that._resize(true);
31130
31131					that._redrawChildren();
31132				}, 100 );
31133			} );
31134
31135			// Redraw the details box on each draw which will happen if the data
31136			// has changed. This is used until DataTables implements a native
31137			// `updated` event for rows
31138			dt.on( 'draw.dtr', function () {
31139				that._redrawChildren();
31140			} );
31141
31142			$(dt.table().node()).addClass( 'dtr-'+details.type );
31143		}
31144
31145		dt.on( 'column-reorder.dtr', function (e, settings, details) {
31146			that._classLogic();
31147			that._resizeAuto();
31148			that._resize(true);
31149		} );
31150
31151		// Change in column sizes means we need to calc
31152		dt.on( 'column-sizing.dtr', function () {
31153			that._resizeAuto();
31154			that._resize();
31155		});
31156
31157		// On Ajax reload we want to reopen any child rows which are displayed
31158		// by responsive
31159		dt.on( 'preXhr.dtr', function () {
31160			var rowIds = [];
31161			dt.rows().every( function () {
31162				if ( this.child.isShown() ) {
31163					rowIds.push( this.id(true) );
31164				}
31165			} );
31166
31167			dt.one( 'draw.dtr', function () {
31168				that._resizeAuto();
31169				that._resize();
31170
31171				dt.rows( rowIds ).every( function () {
31172					that._detailsDisplay( this, false );
31173				} );
31174			} );
31175		});
31176
31177		dt
31178			.on( 'draw.dtr', function () {
31179				that._controlClass();
31180			})
31181			.on( 'init.dtr', function (e, settings, details) {
31182				if ( e.namespace !== 'dt' ) {
31183					return;
31184				}
31185
31186				that._resizeAuto();
31187				that._resize();
31188
31189				// If columns were hidden, then DataTables needs to adjust the
31190				// column sizing
31191				if ( $.inArray( false, that.s.current ) ) {
31192					dt.columns.adjust();
31193				}
31194			} );
31195
31196		// First pass - draw the table for the current viewport size
31197		this._resize();
31198	},
31199
31200
31201	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
31202	 * Private methods
31203	 */
31204
31205	/**
31206	 * Calculate the visibility for the columns in a table for a given
31207	 * breakpoint. The result is pre-determined based on the class logic if
31208	 * class names are used to control all columns, but the width of the table
31209	 * is also used if there are columns which are to be automatically shown
31210	 * and hidden.
31211	 *
31212	 * @param  {string} breakpoint Breakpoint name to use for the calculation
31213	 * @return {array} Array of boolean values initiating the visibility of each
31214	 *   column.
31215	 *  @private
31216	 */
31217	_columnsVisiblity: function ( breakpoint )
31218	{
31219		var dt = this.s.dt;
31220		var columns = this.s.columns;
31221		var i, ien;
31222
31223		// Create an array that defines the column ordering based first on the
31224		// column's priority, and secondly the column index. This allows the
31225		// columns to be removed from the right if the priority matches
31226		var order = columns
31227			.map( function ( col, idx ) {
31228				return {
31229					columnIdx: idx,
31230					priority: col.priority
31231				};
31232			} )
31233			.sort( function ( a, b ) {
31234				if ( a.priority !== b.priority ) {
31235					return a.priority - b.priority;
31236				}
31237				return a.columnIdx - b.columnIdx;
31238			} );
31239
31240		// Class logic - determine which columns are in this breakpoint based
31241		// on the classes. If no class control (i.e. `auto`) then `-` is used
31242		// to indicate this to the rest of the function
31243		var display = $.map( columns, function ( col, i ) {
31244			if ( dt.column(i).visible() === false ) {
31245				return 'not-visible';
31246			}
31247			return col.auto && col.minWidth === null ?
31248				false :
31249				col.auto === true ?
31250					'-' :
31251					$.inArray( breakpoint, col.includeIn ) !== -1;
31252		} );
31253
31254		// Auto column control - first pass: how much width is taken by the
31255		// ones that must be included from the non-auto columns
31256		var requiredWidth = 0;
31257		for ( i=0, ien=display.length ; i<ien ; i++ ) {
31258			if ( display[i] === true ) {
31259				requiredWidth += columns[i].minWidth;
31260			}
31261		}
31262
31263		// Second pass, use up any remaining width for other columns. For
31264		// scrolling tables we need to subtract the width of the scrollbar. It
31265		// may not be requires which makes this sub-optimal, but it would
31266		// require another full redraw to make complete use of those extra few
31267		// pixels
31268		var scrolling = dt.settings()[0].oScroll;
31269		var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;
31270		var widthAvailable = dt.table().container().offsetWidth - bar;
31271		var usedWidth = widthAvailable - requiredWidth;
31272
31273		// Control column needs to always be included. This makes it sub-
31274		// optimal in terms of using the available with, but to stop layout
31275		// thrashing or overflow. Also we need to account for the control column
31276		// width first so we know how much width is available for the other
31277		// columns, since the control column might not be the first one shown
31278		for ( i=0, ien=display.length ; i<ien ; i++ ) {
31279			if ( columns[i].control ) {
31280				usedWidth -= columns[i].minWidth;
31281			}
31282		}
31283
31284		// Allow columns to be shown (counting by priority and then right to
31285		// left) until we run out of room
31286		var empty = false;
31287		for ( i=0, ien=order.length ; i<ien ; i++ ) {
31288			var colIdx = order[i].columnIdx;
31289
31290			if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
31291				// Once we've found a column that won't fit we don't let any
31292				// others display either, or columns might disappear in the
31293				// middle of the table
31294				if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
31295					empty = true;
31296					display[colIdx] = false;
31297				}
31298				else {
31299					display[colIdx] = true;
31300				}
31301
31302				usedWidth -= columns[colIdx].minWidth;
31303			}
31304		}
31305
31306		// Determine if the 'control' column should be shown (if there is one).
31307		// This is the case when there is a hidden column (that is not the
31308		// control column). The two loops look inefficient here, but they are
31309		// trivial and will fly through. We need to know the outcome from the
31310		// first , before the action in the second can be taken
31311		var showControl = false;
31312
31313		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
31314			if ( ! columns[i].control && ! columns[i].never && display[i] === false ) {
31315				showControl = true;
31316				break;
31317			}
31318		}
31319
31320		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
31321			if ( columns[i].control ) {
31322				display[i] = showControl;
31323			}
31324
31325			// Replace not visible string with false from the control column detection above
31326			if ( display[i] === 'not-visible' ) {
31327				display[i] = false;
31328			}
31329		}
31330
31331		// Finally we need to make sure that there is at least one column that
31332		// is visible
31333		if ( $.inArray( true, display ) === -1 ) {
31334			display[0] = true;
31335		}
31336
31337		return display;
31338	},
31339
31340
31341	/**
31342	 * Create the internal `columns` array with information about the columns
31343	 * for the table. This includes determining which breakpoints the column
31344	 * will appear in, based upon class names in the column, which makes up the
31345	 * vast majority of this method.
31346	 *
31347	 * @private
31348	 */
31349	_classLogic: function ()
31350	{
31351		var that = this;
31352		var calc = {};
31353		var breakpoints = this.c.breakpoints;
31354		var dt = this.s.dt;
31355		var columns = dt.columns().eq(0).map( function (i) {
31356			var column = this.column(i);
31357			var className = column.header().className;
31358			var priority = dt.settings()[0].aoColumns[i].responsivePriority;
31359			var dataPriority = column.header().getAttribute('data-priority');
31360
31361			if ( priority === undefined ) {
31362				priority = dataPriority === undefined || dataPriority === null?
31363					10000 :
31364					dataPriority * 1;
31365			}
31366
31367			return {
31368				className: className,
31369				includeIn: [],
31370				auto:      false,
31371				control:   false,
31372				never:     className.match(/\bnever\b/) ? true : false,
31373				priority:  priority
31374			};
31375		} );
31376
31377		// Simply add a breakpoint to `includeIn` array, ensuring that there are
31378		// no duplicates
31379		var add = function ( colIdx, name ) {
31380			var includeIn = columns[ colIdx ].includeIn;
31381
31382			if ( $.inArray( name, includeIn ) === -1 ) {
31383				includeIn.push( name );
31384			}
31385		};
31386
31387		var column = function ( colIdx, name, operator, matched ) {
31388			var size, i, ien;
31389
31390			if ( ! operator ) {
31391				columns[ colIdx ].includeIn.push( name );
31392			}
31393			else if ( operator === 'max-' ) {
31394				// Add this breakpoint and all smaller
31395				size = that._find( name ).width;
31396
31397				for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
31398					if ( breakpoints[i].width <= size ) {
31399						add( colIdx, breakpoints[i].name );
31400					}
31401				}
31402			}
31403			else if ( operator === 'min-' ) {
31404				// Add this breakpoint and all larger
31405				size = that._find( name ).width;
31406
31407				for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
31408					if ( breakpoints[i].width >= size ) {
31409						add( colIdx, breakpoints[i].name );
31410					}
31411				}
31412			}
31413			else if ( operator === 'not-' ) {
31414				// Add all but this breakpoint
31415				for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
31416					if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
31417						add( colIdx, breakpoints[i].name );
31418					}
31419				}
31420			}
31421		};
31422
31423		// Loop over each column and determine if it has a responsive control
31424		// class
31425		columns.each( function ( col, i ) {
31426			var classNames = col.className.split(' ');
31427			var hasClass = false;
31428
31429			// Split the class name up so multiple rules can be applied if needed
31430			for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
31431				var className = classNames[k].trim();
31432
31433				if ( className === 'all' ) {
31434					// Include in all
31435					hasClass = true;
31436					col.includeIn = $.map( breakpoints, function (a) {
31437						return a.name;
31438					} );
31439					return;
31440				}
31441				else if ( className === 'none' || col.never ) {
31442					// Include in none (default) and no auto
31443					hasClass = true;
31444					return;
31445				}
31446				else if ( className === 'control' || className === 'dtr-control' ) {
31447					// Special column that is only visible, when one of the other
31448					// columns is hidden. This is used for the details control
31449					hasClass = true;
31450					col.control = true;
31451					return;
31452				}
31453
31454				$.each( breakpoints, function ( j, breakpoint ) {
31455					// Does this column have a class that matches this breakpoint?
31456					var brokenPoint = breakpoint.name.split('-');
31457					var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
31458					var match = className.match( re );
31459
31460					if ( match ) {
31461						hasClass = true;
31462
31463						if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
31464							// Class name matches breakpoint name fully
31465							column( i, breakpoint.name, match[1], match[2]+match[3] );
31466						}
31467						else if ( match[2] === brokenPoint[0] && ! match[3] ) {
31468							// Class name matched primary breakpoint name with no qualifier
31469							column( i, breakpoint.name, match[1], match[2] );
31470						}
31471					}
31472				} );
31473			}
31474
31475			// If there was no control class, then automatic sizing is used
31476			if ( ! hasClass ) {
31477				col.auto = true;
31478			}
31479		} );
31480
31481		this.s.columns = columns;
31482	},
31483
31484	/**
31485	 * Update the cells to show the correct control class / button
31486	 * @private
31487	 */
31488	_controlClass: function ()
31489	{
31490		if ( this.c.details.type === 'inline' ) {
31491			var dt = this.s.dt;
31492			var columnsVis = this.s.current;
31493			var firstVisible = $.inArray(true, columnsVis);
31494
31495			// Remove from any cells which shouldn't have it
31496			dt.cells(
31497				null,
31498				function(idx) {
31499					return idx !== firstVisible;
31500				},
31501				{page: 'current'}
31502			)
31503				.nodes()
31504				.to$()
31505				.filter('.dtr-control')
31506				.removeClass('dtr-control');
31507
31508			dt.cells(null, firstVisible, {page: 'current'})
31509				.nodes()
31510				.to$()
31511				.addClass('dtr-control');
31512		}
31513	},
31514
31515	/**
31516	 * Show the details for the child row
31517	 *
31518	 * @param  {DataTables.Api} row    API instance for the row
31519	 * @param  {boolean}        update Update flag
31520	 * @private
31521	 */
31522	_detailsDisplay: function ( row, update )
31523	{
31524		var that = this;
31525		var dt = this.s.dt;
31526		var details = this.c.details;
31527
31528		if ( details && details.type !== false ) {
31529			var res = details.display( row, update, function () {
31530				return details.renderer(
31531					dt, row[0], that._detailsObj(row[0])
31532				);
31533			} );
31534
31535			if ( res === true || res === false ) {
31536				$(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
31537			}
31538		}
31539	},
31540
31541
31542	/**
31543	 * Initialisation for the details handler
31544	 *
31545	 * @private
31546	 */
31547	_detailsInit: function ()
31548	{
31549		var that    = this;
31550		var dt      = this.s.dt;
31551		var details = this.c.details;
31552
31553		// The inline type always uses the first child as the target
31554		if ( details.type === 'inline' ) {
31555			details.target = 'td.dtr-control, th.dtr-control';
31556		}
31557
31558		// Keyboard accessibility
31559		dt.on( 'draw.dtr', function () {
31560			that._tabIndexes();
31561		} );
31562		that._tabIndexes(); // Initial draw has already happened
31563
31564		$( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) {
31565			if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
31566				$(this).click();
31567			}
31568		} );
31569
31570		// type.target can be a string jQuery selector or a column index
31571		var target   = details.target;
31572		var selector = typeof target === 'string' ? target : 'td, th';
31573
31574		if ( target !== undefined || target !== null ) {
31575			// Click handler to show / hide the details rows when they are available
31576			$( dt.table().body() )
31577				.on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) {
31578					// If the table is not collapsed (i.e. there is no hidden columns)
31579					// then take no action
31580					if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
31581						return;
31582					}
31583
31584					// Check that the row is actually a DataTable's controlled node
31585					if ( $.inArray( $(this).closest('tr').get(0), dt.rows().nodes().toArray() ) === -1 ) {
31586						return;
31587					}
31588
31589					// For column index, we determine if we should act or not in the
31590					// handler - otherwise it is already okay
31591					if ( typeof target === 'number' ) {
31592						var targetIdx = target < 0 ?
31593							dt.columns().eq(0).length + target :
31594							target;
31595
31596						if ( dt.cell( this ).index().column !== targetIdx ) {
31597							return;
31598						}
31599					}
31600
31601					// $().closest() includes itself in its check
31602					var row = dt.row( $(this).closest('tr') );
31603
31604					// Check event type to do an action
31605					if ( e.type === 'click' ) {
31606						// The renderer is given as a function so the caller can execute it
31607						// only when they need (i.e. if hiding there is no point is running
31608						// the renderer)
31609						that._detailsDisplay( row, false );
31610					}
31611					else if ( e.type === 'mousedown' ) {
31612						// For mouse users, prevent the focus ring from showing
31613						$(this).css('outline', 'none');
31614					}
31615					else if ( e.type === 'mouseup' ) {
31616						// And then re-allow at the end of the click
31617						$(this).trigger('blur').css('outline', '');
31618					}
31619				} );
31620		}
31621	},
31622
31623
31624	/**
31625	 * Get the details to pass to a renderer for a row
31626	 * @param  {int} rowIdx Row index
31627	 * @private
31628	 */
31629	_detailsObj: function ( rowIdx )
31630	{
31631		var that = this;
31632		var dt = this.s.dt;
31633
31634		return $.map( this.s.columns, function( col, i ) {
31635			// Never and control columns should not be passed to the renderer
31636			if ( col.never || col.control ) {
31637				return;
31638			}
31639
31640			var dtCol = dt.settings()[0].aoColumns[ i ];
31641
31642			return {
31643				className:   dtCol.sClass,
31644				columnIndex: i,
31645				data:        dt.cell( rowIdx, i ).render( that.c.orthogonal ),
31646				hidden:      dt.column( i ).visible() && !that.s.current[ i ],
31647				rowIndex:    rowIdx,
31648				title:       dtCol.sTitle !== null ?
31649					dtCol.sTitle :
31650					$(dt.column(i).header()).text()
31651			};
31652		} );
31653	},
31654
31655
31656	/**
31657	 * Find a breakpoint object from a name
31658	 *
31659	 * @param  {string} name Breakpoint name to find
31660	 * @return {object}      Breakpoint description object
31661	 * @private
31662	 */
31663	_find: function ( name )
31664	{
31665		var breakpoints = this.c.breakpoints;
31666
31667		for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
31668			if ( breakpoints[i].name === name ) {
31669				return breakpoints[i];
31670			}
31671		}
31672	},
31673
31674
31675	/**
31676	 * Re-create the contents of the child rows as the display has changed in
31677	 * some way.
31678	 *
31679	 * @private
31680	 */
31681	_redrawChildren: function ()
31682	{
31683		var that = this;
31684		var dt = this.s.dt;
31685
31686		dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
31687			var row = dt.row( idx );
31688
31689			that._detailsDisplay( dt.row( idx ), true );
31690		} );
31691	},
31692
31693
31694	/**
31695	 * Alter the table display for a resized viewport. This involves first
31696	 * determining what breakpoint the window currently is in, getting the
31697	 * column visibilities to apply and then setting them.
31698	 *
31699	 * @param  {boolean} forceRedraw Force a redraw
31700	 * @private
31701	 */
31702	_resize: function (forceRedraw)
31703	{
31704		var that = this;
31705		var dt = this.s.dt;
31706		var width = $(window).innerWidth();
31707		var breakpoints = this.c.breakpoints;
31708		var breakpoint = breakpoints[0].name;
31709		var columns = this.s.columns;
31710		var i, ien;
31711		var oldVis = this.s.current.slice();
31712
31713		// Determine what breakpoint we are currently at
31714		for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
31715			if ( width <= breakpoints[i].width ) {
31716				breakpoint = breakpoints[i].name;
31717				break;
31718			}
31719		}
31720		
31721		// Show the columns for that break point
31722		var columnsVis = this._columnsVisiblity( breakpoint );
31723		this.s.current = columnsVis;
31724
31725		// Set the class before the column visibility is changed so event
31726		// listeners know what the state is. Need to determine if there are
31727		// any columns that are not visible but can be shown
31728		var collapsedClass = false;
31729	
31730		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
31731			if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control && ! dt.column(i).visible() === false ) {
31732				collapsedClass = true;
31733				break;
31734			}
31735		}
31736
31737		$( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
31738
31739		var changed = false;
31740		var visible = 0;
31741
31742		dt.columns().eq(0).each( function ( colIdx, i ) {
31743			if ( columnsVis[i] === true ) {
31744				visible++;
31745			}
31746
31747			if ( forceRedraw || columnsVis[i] !== oldVis[i] ) {
31748				changed = true;
31749				that._setColumnVis( colIdx, columnsVis[i] );
31750			}
31751		} );
31752
31753		if ( changed ) {
31754			this._redrawChildren();
31755
31756			// Inform listeners of the change
31757			$(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
31758
31759			// If no records, update the "No records" display element
31760			if ( dt.page.info().recordsDisplay === 0 ) {
31761				$('td', dt.table().body()).eq(0).attr('colspan', visible);
31762			}
31763		}
31764
31765		that._controlClass();
31766	},
31767
31768
31769	/**
31770	 * Determine the width of each column in the table so the auto column hiding
31771	 * has that information to work with. This method is never going to be 100%
31772	 * perfect since column widths can change slightly per page, but without
31773	 * seriously compromising performance this is quite effective.
31774	 *
31775	 * @private
31776	 */
31777	_resizeAuto: function ()
31778	{
31779		var dt = this.s.dt;
31780		var columns = this.s.columns;
31781
31782		// Are we allowed to do auto sizing?
31783		if ( ! this.c.auto ) {
31784			return;
31785		}
31786
31787		// Are there any columns that actually need auto-sizing, or do they all
31788		// have classes defined
31789		if ( $.inArray( true, $.map( columns, function (c) { return c.auto; }
31789 ) ) === -1 ) {
31790			return;
31791		}
31792
31793		// Need to restore all children. They will be reinstated by a re-render
31794		if ( ! $.isEmptyObject( _childNodeStore ) ) {
31795			$.each( _childNodeStore, function ( key ) {
31796				var idx = key.split('-');
31797
31798				_childNodesRestore( dt, idx[0]*1, idx[1]*1 );
31799			} );
31800		}
31801
31802		// Clone the table with the current data in it
31803		var tableWidth   = dt.table().node().offsetWidth;
31804		var columnWidths = dt.columns;
31805		var clonedTable  = dt.table().node().cloneNode( false );
31806		var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
31807		var clonedBody   = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8
31808
31809		clonedTable.style.width = 'auto';
31810
31811		// Header
31812		var headerCells = dt.columns()
31813			.header()
31814			.filter( function (idx) {
31815				return dt.column(idx).visible();
31816			} )
31817			.to$()
31818			.clone( false )
31819			.css( 'display', 'table-cell' )
31820			.css( 'width', 'auto' )
31821			.css( 'min-width', 0 );
31822
31823		// Body rows - we don't need to take account of DataTables' column
31824		// visibility since we implement our own here (hence the `display` set)
31825		$(clonedBody)
31826			.append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
31827			.find( 'th, td' ).css( 'display', '' );
31828
31829		// Footer
31830		var footer = dt.table().footer();
31831		if ( footer ) {
31832			var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
31833			var footerCells = dt.columns()
31834				.footer()
31835				.filter( function (idx) {
31836					return dt.column(idx).visible();
31837				} )
31838				.to$()
31839				.clone( false )
31840				.css( 'display', 'table-cell' );
31841
31842			$('<tr/>')
31843				.append( footerCells )
31844				.appendTo( clonedFooter );
31845		}
31846
31847		$('<tr/>')
31848			.append( headerCells )
31849			.appendTo( clonedHeader );
31850
31851		// In the inline case extra padding is applied to the first column to
31852		// give space for the show / hide icon. We need to use this in the
31853		// calculation
31854		if ( this.c.details.type === 'inline' ) {
31855			$(clonedTable).addClass( 'dtr-inline collapsed' );
31856		}
31857		
31858		// It is unsafe to insert elements with the same name into the DOM
31859		// multiple times. For example, cloning and inserting a checked radio
31860		// clears the chcecked state of the original radio.
31861		$( clonedTable ).find( '[name]' ).removeAttr( 'name' );
31862
31863		// A position absolute table would take the table out of the flow of
31864		// our container element, bypassing the height and width (Scroller)
31865		$( clonedTable ).css( 'position', 'relative' )
31866		
31867		var inserted = $('<div/>')
31868			.css( {
31869				width: 1,
31870				height: 1,
31871				overflow: 'hidden',
31872				clear: 'both'
31873			} )
31874			.append( clonedTable );
31875
31876		inserted.insertBefore( dt.table().node() );
31877
31878		// The cloned header now contains the smallest that each column can be
31879		headerCells.each( function (i) {
31880			var idx = dt.column.index( 'fromVisible', i );
31881			columns[ idx ].minWidth =  this.offsetWidth || 0;
31882		} );
31883
31884		inserted.remove();
31885	},
31886
31887	/**
31888	 * Get the state of the current hidden columns - controlled by Responsive only
31889	 */
31890	_responsiveOnlyHidden: function ()
31891	{
31892		var dt = this.s.dt;
31893
31894		return $.map( this.s.current, function (v, i) {
31895			// If the column is hidden by DataTables then it can't be hidden by
31896			// Responsive!
31897			if ( dt.column(i).visible() === false ) {
31898				return true;
31899			}
31900			return v;
31901		} );
31902	},
31903
31904	/**
31905	 * Set a column's visibility.
31906	 *
31907	 * We don't use DataTables' column visibility controls in order to ensure
31908	 * that column visibility can Responsive can no-exist. Since only IE8+ is
31909	 * supported (and all evergreen browsers of course) the control of the
31910	 * display attribute works well.
31911	 *
31912	 * @param {integer} col      Column index
31913	 * @param {boolean} showHide Show or hide (true or false)
31914	 * @private
31915	 */
31916	_setColumnVis: function ( col, showHide )
31917	{
31918		var dt = this.s.dt;
31919		var display = showHide ? '' : 'none'; // empty string will remove the attr
31920
31921		$( dt.column( col ).header() ).css( 'display', display );
31922		$( dt.column( col ).footer() ).css( 'display', display );
31923		dt.column( col ).nodes().to$().css( 'display', display );
31924
31925		// If the are child nodes stored, we might need to reinsert them
31926		if ( ! $.isEmptyObject( _childNodeStore ) ) {
31927			dt.cells( null, col ).indexes().each( function (idx) {
31928				_childNodesRestore( dt, idx.row, idx.column );
31929			} );
31930		}
31931	},
31932
31933
31934	/**
31935	 * Update the cell tab indexes for keyboard accessibility. This is called on
31936	 * every table draw - that is potentially inefficient, but also the least
31937	 * complex option given that column visibility can change on the fly. Its a
31938	 * shame user-focus was removed from CSS 3 UI, as it would have solved this
31939	 * issue with a single CSS statement.
31940	 *
31941	 * @private
31942	 */
31943	_tabIndexes: function ()
31944	{
31945		var dt = this.s.dt;
31946		var cells = dt.cells( { page: 'current' } ).nodes().to$();
31947		var ctx = dt.settings()[0];
31948		var target = this.c.details.target;
31949
31950		cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
31951
31952		if ( typeof target === 'number' ) {
31953			dt.cells( null, target, { page: 'current' } ).nodes().to$()
31954				.attr( 'tabIndex', ctx.iTabIndex )
31955				.data( 'dtr-keyboard', 1 );
31956		}
31957		else {
31958			// This is a bit of a hack - we need to limit the selected nodes to just
31959			// those of this table
31960			if ( target === 'td:first-child, th:first-child' ) {
31961				target = '>td:first-child, >th:first-child';
31962			}
31963
31964			$( target, dt.rows( { page: 'current' } ).nodes() )
31965				.attr( 'tabIndex', ctx.iTabIndex )
31966				.data( 'dtr-keyboard', 1 );
31967		}
31968	}
31969} );
31970
31971
31972/**
31973 * List of default breakpoints. Each item in the array is an object with two
31974 * properties:
31975 *
31976 * * `name` - the breakpoint name.
31977 * * `width` - the breakpoint width
31978 *
31979 * @name Responsive.breakpoints
31980 * @static
31981 */
31982Responsive.breakpoints = [
31983	{ name: 'desktop',  width: Infinity },
31984	{ name: 'tablet-l', width: 1024 },
31985	{ name: 'tablet-p', width: 768 },
31986	{ name: 'mobile-l', width: 480 },
31987	{ name: 'mobile-p', width: 320 }
31988];
31989
31990
31991/**
31992 * Display methods - functions which define how the hidden data should be shown
31993 * in the table.
31994 *
31995 * @namespace
31996 * @name Responsive.defaults
31997 * @static
31998 */
31999Responsive.display = {
32000	childRow: function ( row, update, render ) {
32001		if ( update ) {
32002			if ( $(row.node()).hasClass('parent') ) {
32003				row.child( render(), 'child' ).show();
32004
32005				return true;
32006			}
32007		}
32008		else {
32009			if ( ! row.child.isShown()  ) {
32010				row.child( render(), 'child' ).show();
32011				$( row.node() ).addClass( 'parent' );
32012
32013				return true;
32014			}
32015			else {
32016				row.child( false );
32017				$( row.node() ).removeClass( 'parent' );
32018
32019				return false;
32020			}
32021		}
32022	},
32023
32024	childRowImmediate: function ( row, update, render ) {
32025		if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
32026			// User interaction and the row is show, or nothing to show
32027			row.child( false );
32028			$( row.node() ).removeClass( 'parent' );
32029
32030			return false;
32031		}
32032		else {
32033			// Display
32034			row.child( render(), 'child' ).show();
32035			$( row.node() ).addClass( 'parent' );
32036
32037			return true;
32038		}
32039	},
32040
32041	// This is a wrapper so the modal options for Bootstrap and jQuery UI can
32042	// have options passed into them. This specific one doesn't need to be a
32043	// function but it is for consistency in the `modal` name
32044	modal: function ( options ) {
32045		return function ( row, update, render ) {
32046			if ( ! update ) {
32047				// Show a modal
32048				var close = function () {
32049					modal.remove(); // will tidy events for us
32050					$(document).off( 'keypress.dtr' );
32051				};
32052
32053				var modal = $('<div class="dtr-modal"/>')
32054					.append( $('<div class="dtr-modal-display"/>')
32055						.append( $('<div class="dtr-modal-content"/>')
32056							.append( render() )
32057						)
32058						.append( $('<div class="dtr-modal-close">&times;</div>' )
32059							.click( function () {
32060								close();
32061							} )
32062						)
32063					)
32064					.append( $('<div class="dtr-modal-background"/>')
32065						.click( function () {
32066							close();
32067						} )
32068					)
32069					.appendTo( 'body' );
32070
32071				$(document).on( 'keyup.dtr', function (e) {
32072					if ( e.keyCode === 27 ) {
32073						e.stopPropagation();
32074
32075						close();
32076					}
32077				} );
32078			}
32079			else {
32080				$('div.dtr-modal-content')
32081					.empty()
32082					.append( render() );
32083			}
32084
32085			if ( options && options.header ) {
32086				$('div.dtr-modal-content').prepend(
32087					'<h2>'+options.header( row )+'</h2>'
32088				);
32089			}
32090		};
32091	}
32092};
32093
32094
32095var _childNodeStore = {};
32096
32097function _childNodes( dt, row, col ) {
32098	var name = row+'-'+col;
32099
32100	if ( _childNodeStore[ name ] ) {
32101		return _childNodeStore[ name ];
32102	}
32103
32104	// https://jsperf.com/childnodes-array-slice-vs-loop
32105	var nodes = [];
32106	var children = dt.cell( row, col ).node().childNodes;
32107	for ( var i=0, ien=children.length ; i<ien ; i++ ) {
32108		nodes.push( children[i] );
32109	}
32110
32111	_childNodeStore[ name ] = nodes;
32112
32113	return nodes;
32114}
32115
32116function _childNodesRestore( dt, row, col ) {
32117	var name = row+'-'+col;
32118
32119	if ( ! _childNodeStore[ name ] ) {
32120		return;
32121	}
32122
32123	var node = dt.cell( row, col ).node();
32124	var store = _childNodeStore[ name ];
32125	var parent = store[0].parentNode;
32126	var parentChildren = parent.childNodes;
32127	var a = [];
32128
32129	for ( var i=0, ien=parentChildren.length ; i<ien ; i++ ) {
32130		a.push( parentChildren[i] );
32131	}
32132
32133	for ( var j=0, jen=a.length ; j<jen ; j++ ) {
32134		node.appendChild( a[j] );
32135	}
32136
32137	_childNodeStore[ name ] = undefined;
32138}
32139
32140
32141/**
32142 * Display methods - functions which define how the hidden data should be shown
32143 * in the table.
32144 *
32145 * @namespace
32146 * @name Responsive.defaults
32147 * @static
32148 */
32149Responsive.renderer = {
32150	listHiddenNodes: function () {
32151		return function ( api, rowIdx, columns ) {
32152			var ul = $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>');
32153			var found = false;
32154
32155			var data = $.each( columns, function ( i, col ) {
32156				if ( col.hidden ) {
32157					var klass = col.className ?
32158						'class="'+ col.className +'"' :
32159						'';
32160	
32161					$(
32162						'<li '+klass+' data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
32163							'<span class="dtr-title">'+
32164								col.title+
32165							'</span> '+
32166						'</li>'
32167					)
32168						.append( $('<span class="dtr-data"/>').append( _childNodes( api, col.rowIndex, col.columnIndex ) ) )// api.cell( col.rowIndex, col.columnIndex ).node().childNodes ) )
32169						.appendTo( ul );
32170
32171					found = true;
32172				}
32173			} );
32174
32175			return found ?
32176				ul :
32177				false;
32178		};
32179	},
32180
32181	listHidden: function () {
32182		return function ( api, rowIdx, columns ) {
32183			var data = $.map( columns, function ( col ) {
32184				var klass = col.className ?
32185					'class="'+ col.className +'"' :
32186					'';
32187
32188				return col.hidden ?
32189					'<li '+klass+' data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
32190						'<span class="dtr-title">'+
32191							col.title+
32192						'</span> '+
32193						'<span class="dtr-data">'+
32194							col.data+
32195						'</span>'+
32196					'</li>' :
32197					'';
32198			} ).join('');
32199
32200			return data ?
32201				$('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>').append( data ) :
32202				false;
32203		}
32204	},
32205
32206	tableAll: function ( options ) {
32207		options = $.extend( {
32208			tableClass: ''
32209		}, options );
32210
32211		return function ( api, rowIdx, columns ) {
32212			var data = $.map( columns, function ( col ) {
32213				var klass = col.className ?
32214					'class="'+ col.className +'"' :
32215					'';
32216
32217				return '<tr '+klass+' data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
32218						'<td>'+col.title+':'+'</td> '+
32219						'<td>'+col.data+'</td>'+
32220					'</tr>';
32221			} ).join('');
32222
32223			return $('<table class="'+options.tableClass+' dtr-details" width="100%"/>').append( data );
32224		}
32225	}
32226};
32227
32228/**
32229 * Responsive default settings for initialisation
32230 *
32231 * @namespace
32232 * @name Responsive.defaults
32233 * @static
32234 */
32235Responsive.defaults = {
32236	/**
32237	 * List of breakpoints for the instance. Note that this means that each
32238	 * instance can have its own breakpoints. Additionally, the breakpoints
32239	 * cannot be changed once an instance has been creased.
32240	 *
32241	 * @type {Array}
32242	 * @default Takes the value of `Responsive.breakpoints`
32243	 */
32244	breakpoints: Responsive.breakpoints,
32245
32246	/**
32247	 * Enable / disable auto hiding calculations. It can help to increase
32248	 * performance slightly if you disable this option, but all columns would
32249	 * need to have breakpoint classes assigned to them
32250	 *
32251	 * @type {Boolean}
32252	 * @default  `true`
32253	 */
32254	auto: true,
32255
32256	/**
32257	 * Details control. If given as a string value, the `type` property of the
32258	 * default object is set to that value, and the defaults used for the rest
32259	 * of the object - this is for ease of implementation.
32260	 *
32261	 * The object consists of the following properties:
32262	 *
32263	 * * `display` - A function that is used to show and hide the hidden details
32264	 * * `renderer` - function that is called for display of the child row data.
32265	 *   The default function will show the data from the hidden columns
32266	 * * `target` - Used as the selector for what objects to attach the child
32267	 *   open / close to
32268	 * * `type` - `false` to disable the details display, `inline` or `column`
32269	 *   for the two control types
32270	 *
32271	 * @type {Object|string}
32272	 */
32273	details: {
32274		display: Responsive.display.childRow,
32275
32276		renderer: Responsive.renderer.listHidden(),
32277
32278		target: 0,
32279
32280		type: 'inline'
32281	},
32282
32283	/**
32284	 * Orthogonal data request option. This is used to define the data type
32285	 * requested when Responsive gets the data to show in the child row.
32286	 *
32287	 * @type {String}
32288	 */
32289	orthogonal: 'display'
32290};
32291
32292
32293/*
32294 * API
32295 */
32296var Api = $.fn.dataTable.Api;
32297
32298// Doesn't do anything - work around for a bug in DT... Not documented
32299Api.register( 'responsive()', function () {
32300	return this;
32301} );
32302
32303Api.register( 'responsive.index()', function ( li ) {
32304	li = $(li);
32305
32306	return {
32307		column: li.data('dtr-index'),
32308		row:    li.parent().data('dtr-index')
32309	};
32310} );
32311
32312Api.register( 'responsive.rebuild()', function () {
32313	return this.iterator( 'table', function ( ctx ) {
32314		if ( ctx._responsive ) {
32315			ctx._responsive._classLogic();
32316		}
32317	} );
32318} );
32319
32320Api.register( 'responsive.recalc()', function () {
32321	return this.iterator( 'table', function ( ctx ) {
32322		if ( ctx._responsive ) {
32323			ctx._responsive._resizeAuto();
32324			ctx._responsive._resize();
32325		}
32326	} );
32327} );
32328
32329Api.register( 'responsive.hasHidden()', function () {
32330	var ctx = this.context[0];
32331
32332	return ctx._responsive ?
32333		$.inArray( false, ctx._responsive._responsiveOnlyHidden() ) !== -1 :
32334		false;
32335} );
32336
32337Api.registerPlural( 'columns().responsiveHidden()', 'column().responsiveHidden()', function () {
32338	return this.iterator( 'column', function ( settings, column ) {
32339		return settings._responsive ?
32340			settings._responsive._responsiveOnlyHidden()[ column ] :
32341			false;
32342	}, 1 );
32343} );
32344
32345
32346/**
32347 * Version information
32348 *
32349 * @name Responsive.version
32350 * @static
32351 */
32352Responsive.version = '2.2.9';
32353
32354
32355$.fn.dataTable.Responsive = Responsive;
32356$.fn.DataTable.Responsive = Responsive;
32357
32358// Attach a listener to the document which listens for DataTables initialisation
32359// events so we can automatically initialise
32360$(document).on( 'preInit.dt.dtr', function (e, settings, json) {
32361	if ( e.namespace !== 'dt' ) {
32362		return;
32363	}
32364
32365	if ( $(settings.nTable).hasClass( 'responsive' ) ||
32366		 $(settings.nTable).hasClass( 'dt-responsive' ) ||
32367		 settings.oInit.responsive ||
32368		 DataTable.defaults.responsive
32369	) {
32370		var init = settings.oInit.responsive;
32371
32372		if ( init !== false ) {
32373			new Responsive( settings, $.isPlainObject( init ) ? init : {}  );
32374		}
32375	}
32376} );
32377
32378
32379return Responsive;
32380}));
32381
32382
32383/***/ }),
32384/* 16 */
32385/***/ (function(module, exports, __webpack_require__) {
32386
32387/* WEBPACK VAR INJECTION */(function(Buffer, global, setImmediate) {var require;var require;/*!
32388
32389JSZip v3.7.1 - A JavaScript class for generating and reading zip files
32390<http://stuartk.com/jszip>
32391
32392(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>
32393Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.
32394
32395JSZip uses the library pako released under the MIT license :
32396https://github.com/nodeca/pako/blob/master/LICENSE
32397*/
32398
32399!function(t){if(true)module.exports=t();else {}}(function(){return function s(a,o,h){function u(r,t){if(!o[r]){if(!a[r]){var e="function"==typeof require&&require;if(!t&&e)return requir
vendor: 5,404 bytes, line 32399
32399e(r,!0);if(l)return l(r,!0);var i=new Error("Cannot find module '"+r+"'");throw i.code="MODULE_NOT_FOUND",i}var n=o[r]={exports:{}};a[r][0].call(n.exports,function(t){var e=a[r][1][t];return u(e||t)},n,n.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,t=0;t<h.length;t++)u(h[t]);return u}({1:[function(t,e,r){"use strict";var c=t("./utils"),d=t("./support"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.encode=function(t){for(var e,r,i,n,s,a,o,h=[],u=0,l=t.length,f=l,d="string"!==c.getTypeOf(t);u<t.length;)f=l-u,i=d?(e=t[u++],r=u<l?t[u++]:0,u<l?t[u++]:0):(e=t.charCodeAt(u++),r=u<l?t.charCodeAt(u++):0,u<l?t.charCodeAt(u++):0),n=e>>2,s=(3&e)<<4|r>>4,a=1<f?(15&r)<<2|i>>6:64,o=2<f?63&i:64,h.push(p.charAt(n)+p.charAt(s)+p.charAt(a)+p.charAt(o));return h.join("")},r.decode=function(t){var e,r,i,n,s,a,o=0,h=0,u="data:";if(t.substr(0,u.length)===u)throw new Error("Invalid base64 input, it looks like a data url.");var l,f=3*(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"")).length/4;if(t.charAt(t.length-1)===p.charAt(64)&&f--,t.charAt(t.length-2)===p.charAt(64)&&f--,f%1!=0)throw new Error("Invalid base64 input, bad content length.");for(l=d.uint8array?new Uint8Array(0|f):new Array(0|f);o<t.length;)e=p.indexOf(t.charAt(o++))<<2|(n=p.indexOf(t.charAt(o++)))>>4,r=(15&n)<<4|(s=p.indexOf(t.charAt(o++)))>>2,i=(3&s)<<6|(a=p.indexOf(t.charAt(o++))),l[h++]=e,64!==s&&(l[h++]=r),64!==a&&(l[h++]=i);return l}},{"./support":30,"./utils":32}],2:[function(t,e,r){"use strict";var i=t("./external"),n=t("./stream/DataWorker"),s=t("./stream/Crc32Probe"),a=t("./stream/DataLengthProbe");function o(t,e,r,i,n){this.compressedSize=t,this.uncompressedSize=e,this.crc32=r,this.compression=i,this.compressedContent=n}o.prototype={getContentWorker:function(){var t=new n(i.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),e=this;return t.on("end",function(){if(this.streamInfo.data_length!==e.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),t},getCompressedWorker:function(){return new n(i.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(t,e,r){return t.pipe(new s).pipe(new a("uncompressedSize")).pipe(e.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",e)},e.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(t,e,r){"use strict";var i=t("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(t){return new i("STORE compression")},uncompressWorker:function(){return new i("STORE decompression")}},r.DEFLATE=t("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(t,e,r){"use strict";var i=t("./utils");var o=function(){for(var t,e=[],r=0;r<256;r++){t=r;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[r]=t}return e}();e.exports=function(t,e){return void 0!==t&&t.length?"string"!==i.getTypeOf(t)?function(t,e,r,i){var n=o,s=i+r;t^=-1;for(var a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return-1^t}(0|e,t,t.length,0):function(t,e,r,i){var n=o,s=i+r;t^=-1;for(var a=i;a<s;a++)t=t>>>8^n[255&(t^e.charCodeAt(a))];return-1^t}(0|e,t,t.length,0):0}},{"./utils":32}],5:[function(t,e,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(t,e,r){"use strict";var i=null;i="undefined"!=typeof Promise?Promise:t("lie"),e.exports={Promise:i}},{lie:37}],7:[function(t,e,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,n=t("pako"),s=t("./utils"),a=t("./stream/GenericWorker"),o=i?"uint8array":"array";function h(t,e){a.call(this,"FlateWorker/"+t),this._pako=null,this._pakoAction=t,this._pakoOptions=e,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(t){this.meta=t.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,t.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new n[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var e=this;this._pako.onData=function(t){e.push({data:t,meta:e.meta})}},r.compressWorker=function(t){return new h("Deflate",t)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(t,e,r){"use strict";function A(t,e){var r,i="";for(r=0;r<e;r++)i+=String.fromCharCode(255&t),t>>>=8;return i}function i(t,e,r,i,n,s){var a,o,h=t.file,u=t.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),d=I.transformTo("string",O.utf8encode(h.name)),c=h.comment,p=I.transformTo("string",s(c)),m=I.transformTo("string",O.utf8encode(c)),_=d.length!==h.name.length,g=m.length!==c.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};e&&!r||(x.crc32=t.crc32,x.compressedSize=t.compressedSize,x.uncompressedSize=t.uncompressedSize);var S=0;
vendor: 89,589 bytes, line 32399
32399e&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===n?(C=798,z|=function(t,e){var r=t;return t||(r=e?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(t){return 63&(t||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+d,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(i,4)+f+b+p}}var I=t("../utils"),n=t("../stream/GenericWorker"),O=t("../utf8"),B=t("../crc32"),R=t("../signature");function s(t,e,r,i){n.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=e,this.zipPlatform=r,this.encodeFileName=i,this.streamFiles=t,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,n),s.prototype.push=function(t){var e=t.meta.percent||0,r=this.entriesCount,i=this._sources.length;this.accumulate?this.contentBuffer.push(t):(this.bytesWritten+=t.data.length,n.prototype.push.call(this,{data:t.data,meta:{currentFile:this.currentFile,percent:r?(e+100*(r-i-1))/r:100}}))},s.prototype.openedSource=function(t){this.currentSourceOffset=this.bytesWritten,this.currentFile=t.file.name;var e=this.streamFiles&&!t.file.dir;if(e){var r=i(t,e,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(t){this.accumulate=!1;var e=this.streamFiles&&!t.file.dir,r=i(t,e,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),e)this.push({data:function(t){return R.DATA_DESCRIPTOR+A(t.crc32,4)+A(t.compressedSize,4)+A(t.uncompressedSize,4)}(t),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var t=this.bytesWritten,e=0;e<this.dirRecords.length;e++)this.push({data:this.dirRecords[e],meta:{percent:100}});var r=this.bytesWritten-t,i=function(t,e,r,i,n){var s=I.transformTo("string",n(i));return R.CENTRAL_DIRECTORY_END+"\0\0\0\0"+A(t,2)+A(t,2)+A(e,4)+A(r,4)+A(s.length,2)+s}(this.dirRecords.length,r,t,this.zipComment,this.encodeFileName);this.push({data:i,meta:{percent:100}})},s.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},s.prototype.registerPrevious=function(t){this._sources.push(t);var e=this;return t.on("data",function(t){e.processChunk(t)}),t.on("end",function(){e.closedSource(e.previous.streamInfo),e._sources.length?e.prepareNextSource():e.end()}),t.on("error",function(t){e.error(t)}),this},s.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},s.prototype.error=function(t){var e=this._sources;if(!n.prototype.error.call(this,t))return!1;for(var r=0;r<e.length;r++)try{e[r].error(t)}catch(t){}return!0},s.prototype.lock=function(){n.prototype.lock.call(this);for(var t=this._sources,e=0;e<t.length;e++)t[e].lock()},e.exports=s},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(t,e,r){"use strict";var u=t("../compressions"),i=t("./ZipFileWorker");r.generateWorker=function(t,a,e){var o=new i(a.streamFiles,e,a.platform,a.encodeFileName),h=0;try{t.forEach(function(t,e){h++;var r=function(t,e){var r=t||e,i=u[r];if(!i)throw new Error(r+" is not a valid compression method !");return i}(e.options.compression,a.compression),i=e.options.compressionOptions||a.compressionOptions||{},n=e.dir,s=e.date;e._compressWorker(r,i).withStreamInfo("file",{name:t,dir:n,date:s,comment:e.comment||"",unixPermissions:e.unixPermissions,dosPermissions:e.dosPermissions}).pipe(o)}),o.entriesCount=h}catch(t){o.error(t)}return o}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(t,e,r){"use strict";function i(){if(!(this instanceof i))return new i;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files=Object.create(null),this.comment=null,this.root="",this.clone=function(){var t=new i;for(var e in this)"function"!=typeof this[e]&&(t[e]=this[e]);return t}}(i.prototype=t("./object")).loadAsync=t("./load"),i.support=t("./support"),i.defaults=t("./defaults"),i.version="3.7.1",i.loadAsync=function(t,e){return(new i).loadAsync(t,e)},i.external=t("./external"),e.exports=i},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(t,e,r){"use strict";var i=t("./utils"),n=t("./external"),o=t("./utf8"),h=t("./zipEntries"),s=t("./stream/Crc32Probe"),u=t("./nodejsUtils");function l(i){return new n.Promise(function(t,e){var r=i.decompressed.getContentWorker().pipe(new s);r.on("error",function(t){e(t)}).on("end",function(){r.streamInfo.crc32!==i.decompressed.crc32?e(new Error("Corrupted zip : CRC32 mismatch")):t()}).resume()})}e.exports=function(t,s){var a=this;return s=i.extend(s||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:o.utf8decode}),u.isNode&&u.isStream(t)?n.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):i.prepareContent("the loaded zip file",t,!0,s.optimizedBinaryString,s.base64).then(function(t){var e=new h(s);return e.load(t),e}).then(function(t){var e=[n.Promise.resolve(t)],r=t.files;if(s.checkCRC32)for(var i=0;i<r.length;i++)e.push(l(r[i]));return n.Promise.all(e)}).then(function(t){for(var e=t.shift(),r=e.files,i=0;i<r.length;i++){var n=r[i];a.file(n.fileNameStr,n.decompressed,{binary:!0,optimizedBinaryString:!0,date:n.date,dir:n.dir,comment:n.fileCommentStr.length?n.fileCommentStr:null,unixPermissions:n.unixPermissions,dosPermissions:n.dosPermissions,createFolders:s.createFolders})}return e.zipComment.length&&(a.comment=e.zipComment),a})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(t,e,r){"use strict";var i=t("../utils"),n=t("../stream/GenericWorker");function s(t,e){n.call(this,"Nodejs stream input adapter for "+t),this._upstreamEnded=!1,this._bindStream(e)}i.inherits(s,n),s.prototype._bindStream=function(t){var e=this;(this._stream=t).pause(),t.on("data",function(t){e.push({data:t,meta:{percent:0}})}).on("error",function(t){e.isPaused?this.generatedError=t:e.error(t)}).on("end",function(){e.isPaused?e._upstreamEnded=!0:e.end()})},s.prototype.pause=function(){return!!n.prototype.pause.call(this)&&(this._stream.pause(),!0)},s.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},e.exports=s},{"../stream/GenericWorker":28,"../utils":32}],13:[function(t,e,r){"use strict";var n=t("readable-stream").Readable;function i(t,e,r){n.call(this,e),this._helper=t;var i=this;t.on("data",function(t,e){i.push(t)||i._helper.pause(),r&&r(e)}).on("error",function(t){i.emit("error",t)}).on("end",function(){i.push(null)})}t("../utils").inherits(i,n),i.prototype._read=function(){this._helper.resume()},e.exports=i},{"../utils":32,"readable-stream":16}],14:[function(t,e,r){"use strict";e.exports={isNode:"undefined"!=typeof Buffer,newBufferFrom:function(t,e){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(t,e);if("number"==typeof t)throw new Error('The "data" argument must not be a number');return new Buffer(t,e)},allocBuffer:function(t){if(Buffer.alloc)return Buffer.alloc(t);var e=new Buffer(t);return e.fill(0),e},isBuffer:function(t){return Buffer.isBuffer(t)},isStream:function(t){return t&&"function"==typeof t.on&&"function"==typeof t.pause&&"function"==typeof t.resume}}},{}],15:[function(t,e,r){"use strict";function s(t,e,r){var i,n=u.getTypeOf(e),s=u.extend(r||{},f);s.date=s.date||new Date,null!==s.compression&&(s.compression=s.compression.toUpperCase()),"string"==typeof s.unixPermissions&&(s.unixPermissions=parseInt(s.unixPermissions,8)),s.unixPermissions&&16384&s.unixPermissions&&(s.dir=!0),s.dosPermissions&&16&s.dosPermissions&&(s.dir=!0),s.dir&&(t=g(t)),s.createFolders&&(i=_(t))&&b.call(this,i,!0);var a="string"===n&&!1===s.binary&&!1===s.base64;r&&void 0!==r.binary||(s.binary=!a),(e instanceof d&&0===e.uncompressedSize||s.dir||!e||0===e.length)&&(s.base64=!1,s.binary=!0,e="",s.compression="STORE",n="string");var o=null;o=e instanceof d||e instanceof l?e:p.isNode&&p.isStream(e)?new m(t,e):u.prepareContent(t,e,s.binary,s.optimizedBinaryString,s.base64);var h=new c(t,o,s);this.files[t]=h}var n=t("./utf8"),u=t("./utils"),l=t("./stream/GenericWorker"),a=t("./stream/StreamHelper"),f=t("./defaults"),d=t("./compressedObject"),c=t("./zipObject"),o=t("./generate"),p=t("./nodejsUtils"),m=t("./nodejs/NodejsStreamInputAdapter"),_=function(t){"/"===t.slice(-1)&&(t=t.substring(0,t.length-1));var e=t.lastIndexOf("/");return 0<e?t.substring(0,e):""},g=function(t){return"/"!==t.slice(-1)&&(t+="/"),t},b=function(t,e){return e=void 0!==e?e:f.createFolders,t=g(t),this.files[t]||s.call(this,t,null,{dir:!0,createFolders:e}),this.files[t]};function h(t){return"[object RegExp]"===Object.prototype.toString.call(t)}var i={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(t){var e,r,i;for(e in this.files)i=this.files[e],(r=e.slice(this.root.length,e.length))&&e.slice(0,this.root.length)===this.root&&t(r,i)},filter:function(r){var i=[];return this.forEach(function(t,e){r(t,e)&&i.push(e)}),i},file:function(t,e,r){if(1!==arguments.length)return t=this.root+t,s.call(this,t,e,r),this;if(h(t)){var i=t;return this.filter(function(t,e){return!e.dir&&i.test(t)})}var n=this.files[this.root+t];return n&&!n.dir?n:null},folder:function(r){if(!r)return this;if(h(r))return this.filter(function(t,e){return e.dir&&r.test(t)});var t=this.root+r,e=b.call(this,t),i=this.clone();return i.root=e.name,i},remove:function(r){r=this.root+r;var t=this.files[r];if(t||("/"!==r.slice(-1)&&(r+="/"),t=this.files[r]),t&&!t.dir)delete this.files[r];else for(var e=this.filter(function(t,e){return e.name.slice(0,r.length)===r}),i=0;i<e.length;i++)delete this.files[e[i].name];return this},generate:function(t){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(t){var e,r={};try{if((r=u.extend(t||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:n.utf8encode})).type=r.type.toLowerCase(),r.compression=r.compression.toUpperCase(),"binarystring"===r.type&&(r.type="string"),!r.type)throw new Error("No output type specified.");u.checkSupport(r.type),"darwin"!==r.platform&&"freebsd"!==r.platform&&"linux"!==r.platform&&"sunos"!==r.platform||(r.platform="UNIX"),"win32"===r.platform&&(r.platform="DOS");var i=r.comment||this.comment||"";e=o.generateWorker(this,r,i)}catch(t){(e=new l("error")).error(t)}return new a(e,r.type||"string",r.mimeType)},generateAsync:function(t,e){return this.generateInternalStream(t).accumulate(e)},generateNodeStream:function(t,e){return(t=t||{}).type||(t.type="nodebuffer"),this.generateInternalStream(t).toNodejsStream(e)}};e.exports=i},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(t,e,r){e.exports=t("stream")},{stream:void 0}],17:[function(t,e,r){"use strict";var i=t("./DataReader");function n(t){i.call(this,t);for(var e=0;e<this.data.length;e++)t[e]=255&t[e]}t("../utils").inherits(n,i),n.prototype.byteAt=function(t){return this.data[this.zero+t]},n.prototype.lastIndexOfSignature=function(t){for(var e=t.charCodeAt(0),r=t.charCodeAt(1),i=t.charCodeAt(2),n=t.charCodeAt(3),s=this.length-4;0<=s;--s)if(this.data[s]===e&&this.data[s+1]===r&&this.data[s+2]===i&&this.data[s+3]===n)return s-this.zero;return-1},n.prototype.readAndCheckSignature=function(t){var e=t.charCodeAt(0),r=t.charCodeAt(1),i=t.charCodeAt(2),n=t.charCodeAt(3),s=this.readData(4);return e===s[0]&&r===s[1]&&i===s[2]&&n===s[3]},n.prototype.readData=function(t){if(this.checkOffset(t),0===t)return[];var e=this.data.slice(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./DataReader":18}],18:[function(t,e,r){"use strict";var i=t("../utils");function n(t){this.data=t,this.length=t.length,this.index=0,this.zero=0}n.prototype={checkOffset:function(t){this.checkIndex(this.index+t)},checkIndex:function(t){if(this.length<this.zero+t||t<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+t+"). Corrupted zip ?")},setIndex:function(t){this.checkIndex(t),this.index=t},skip:function(t){this.setIndex(this.index+t)},byteAt:function(t){},readInt:function(t){var e,r=0;for(this.checkOffset(t),e=this.index+t-1;e>=this.index;e--)r=(r<<8)+this.byteAt(e);return this.index+=t,r},readString:function(t){return i.transformTo("string",this.readData(t))},readData:function(t){},lastIndexOfSignature:function(t){},readAndCheckSignature:function(t){},readDate:function(){var t=this.readInt(4);return new Date(Date.UTC(1980+(t>>25&127),(t>>21&15)-1,t>>16&31,t>>11&31,t>>5&63,(31&t)<<1))}},e.exports=n},{"../utils":32}],19:[function(t,e,r){"use strict";var i=t("./Uint8ArrayReader");function n(t){i.call(this,t)}t("../utils").inherits(n,i),n.prototype.readData=function(t){this.checkOffset(t);var e=this.data.slice(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(t,e,r){"use strict";var i=t("./DataReader");function n(t){i.call(this,t)}t("../utils").inherits(n,i),n.prototype.byteAt=function(t){return this.data.charCodeAt(this.zero+t)},n.prototype.lastIndexOfSignature=function(t){return this.data.lastIndexOf(t)-this.zero},n.prototype.readAndCheckSignature=function(t){return t===this.readData(4)},n.prototype.readData=function(t){this.checkOffset(t);var e=this.data.slice(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./DataReader":18}],21:[function(t,e,r){"use strict";var i=t("./ArrayReader");function n(t){i.call(this,t)}t("../utils").inherits(n,i),n.prototype.readData=function(t){if(this.checkOffset(t),0===t)return new Uint8Array(0);var e=this.data.subarray(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./ArrayReader":17}],22:[function(t,e,r){"use strict";var i=t("../utils"),n=t("../support"),s=t("./ArrayReader"),a=t("./StringReader"),o=t("./NodeBufferReader"),h=t("./Uint8ArrayReader");e.exports=function(t){var e=i.getTypeOf(t);return i.checkSupport(e),"string"!==e||n.uint8array?"nodebuffer"===e?new o(t):n.uint8array?new h(i.transformTo("uint8array",t)):new s(i.transformTo("array",t)):new a(t)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(t,e,r){"use strict";r.LOCAL_FILE_HEADER="PK��",r.CENTRAL_FILE_HEADER="PK��",r.CENTRAL_DIRECTORY_END="PK��",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK��",r.ZIP64_CENTRAL_DIRECTORY_END="PK��",r.DATA_DESCRIPTOR="PK�\b"},{}],24:[function(t,e,r){"use strict";var i=t("./GenericWorker"),n=t("../utils");function s(t){i.call(this,"ConvertWorker to "+t),this.destType=t}n.inherits(s,i),s.prototype.processChunk=function(t){this.push({data:n.transformTo(this.destType,t.data),meta:t.meta})},e.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(t,e,r){"use strict";var i=t("./GenericWorker"),n=t("../crc32");function s(){i.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}t("../utils").inherits(s,i),s.prototype.processChunk=function(t){this.streamInfo.crc32=n(t.data,this.streamInfo.crc32||0),this.push(t)},e.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(t,e,r){"use strict";var i=t("../utils"),n=t("./GenericWorker");function s(t){n.call(this,"DataLengthProbe for "+t),this.propName=t,this.withStreamInfo(t,0)}i.inherits(s,n),s.prototype.processChunk=function(t){if(t){var e=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=e+t.data.length}n.prototype.processChunk.call(this,t)},e.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(t,e,r){"use strict";var i=t("../utils"),n=t("./GenericWorker");function s(t){n.call(this,"DataWorker");var e=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,t.then(function(t){e.dataIsReady=!0,e.data=t,e.max=t&&t.length||0,e.type=i.getTypeOf(t),e.isPaused||e._tickAndRepeat()},function(t){e.error(t)})}i.inherits(s,n),s.prototype.cleanUp=function(){n.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,i.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(i.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var t=null,e=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":t=this.data.substring(this.index,e);break;case"uint8array":t=this.data.subarray(this.index,e);break;case"array":case"nodebuffer":t=this.data.slice(this.index,e)}return this.index=e,this.push({data:t,meta:{percent:this.max?this.index/this.max*100:0}})},e.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(t,e,r){"use strict";function i(t){this.name=t||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}i.prototype={push:function(t){this.emit("data",t)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(t){this.emit("error",t)}return!0},error:function(t){return!this.isFinished&&(this.isPaused?this.generatedError=t:(this.isFinished=!0,this.emit("error",t),this.previous&&this.previous.error(t),this.cleanUp()),!0)},on:function(t,e){return this._listeners[t].push(e),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(t,e){if(this._listeners[t])for(var r=0;r<this._listeners[t].length;r++)this._listeners[t][r].call(this,e)},pipe:function(t){return t.registerPrevious(this)},registerPrevious:function(t){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=t.streamInfo,this.mergeStreamInfo(),this.previous=t;var e=this;return t.on("data",function(t){e.processChunk(t)}),t.on("end",function(){e.end()}),t.on("error",function(t){e.error(t)}),this},pause:function(){return!this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return!1;var t=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),t=!0),this.previous&&this.previous.resume(),!t},flush:function(){},processChunk:function(t){this.push(t)},withStreamInfo:function(t,e){return this.extraStreamInfo[t]=e,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var t in this.extraStreamInfo)this.extraStreamInfo.hasOwnProperty(t)&&(this.streamInfo[t]=this.extraStreamInfo[t])},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock()},toString:function(){var t="Worker "+this.name;return this.previous?this.previous+" -> "+t:t}},e.exports=i},{}],29:[function(t,e,r){"use strict";var h=t("../utils"),n=t("./ConvertWorker"),s=t("./GenericWorker"),u=t("../base64"),i=t("../support"),a=t("../external"),o=null;if(i.nodestream)try{o=t("../nodejs/NodejsStreamOutputAdapter")}catch(t){}function l(t,o){return new a.Promise(function(e,r){var i=[],n=t._internalType,s=t._outputType,a=t._mimeType;t.on("data",function(t,e){i.push(t),o&&o(e)}).on("error",function(t){i=[],r(t)}).on("end",function(){try{var t=function(t,e,r){switch(t){case"blob":return h.newBlob(h.transformTo("arraybuffer",e),r);case"base64":return u.encode(e);default:return h.transformTo(t,e)}}(s,function(t,e){var r,i=0,n=null,s=0;for(r=0;r<e.length;r++)s+=e[r].length;switch(t){case"string":return e.join("");case"array":return Array.prototype.concat.apply([],e);case"uint8array":for(n=new Uint8Array(s),r=0;r<e.length;r++)n.set(e[r],i),i+=e[r].length;return n;case"nodebuffer":return Buffer.concat(e);default:throw new Error("concat : unsupported type '"+t+"'")}}(n,i),a);e(t)}catch(t){r(t)}i=[]}).resume()})}function f(t,e,r){var i=e;switch(e){case"blob":case"arraybuffer":i="uint8array";break;case"base64":i="string"}try{this._internalType=i,this._outputType=e,this._mimeType=r,h.checkSupport(i),this._worker=t.pipe(new n(i)),t.lock()}catch(t){this._worker=new s("error"),this._worker.error(t)}}f.prototype={accumulate:function(t){return l(this,t)},on:function(t,e){var r=this;return"data"===t?this._worker.on(t,function(t){e.call(r,t.data,t.meta)}):this._worker.on(t,function(){h.delay(e,arguments,r)}),this},resume:function(){return h.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(t){if(h.checkSupport("nodestream"),"nodebuffer"!==this._outputType)throw new Error(this._outputType+" is not supported by this method");return new o(this,{objectMode:"nodebuffer"!==this._outputType},t)}},e.exports=f},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(t,e,r){"use strict";if(r.base64=!0,r.array=!0,r.string=!0,r.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,r.nodebuffer="undefined"!=typeof Buffer,r.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)r.blob=!1;else{var i=new ArrayBuffer(0);try{r.blob=0===new Blob([i],{type:"application/zip"}).size}catch(t){try{var n=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);n.append(i),r.blob=0===n.getBlob("application/zip").size}catch(t){r.blob=!1}}}try{r.nodestream=!!t("readable-stream").Readable}catch(t){r.nodestream=!1}},{"readable-stream":16}],31:[function(t,e,s){"use strict";for(var o=t("./utils"),h=t("./support"),r=t("./nodejsUtils"),i=t("./stream/GenericWorker"),u=new Array(256),n=0;n<256;n++)u[n]=252<=n?6:248<=n?5:240<=n?4:224<=n?3:192<=n?2:1;u[254]=u[254]=1;function a(){i.call(this,"utf-8 decode"),this.leftOver=null}function l(){i.call(this,"utf-8 encode")}s.utf8encode=function(t){return h.nodebuffer?r.newBufferFrom(t,"utf-8"):function(t){var e,r,i,n,s,a=t.length,o=0;for(n=0;n<a;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),o+=r<128?1:r<2048?2:r<65536?3:4;for(e=h.uint8array?new Uint8Array(o):new Array(o),n=s=0;s<o;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),r<128?e[s++]=r:(r<2048?e[s++]=192|r>>>6:(r<65536?e[s++]=224|r>>>12:(e[s++]=240|r>>>18,e[s++]=128|r>>>12&63),e[s++]=128|r>>>6&63),e[s++]=128|63&r);return e}(t)},s.utf8decode=function(t){return h.nodebuffer?o.transformTo("nodebuffer",t).toString("utf-8"):function(t){var e,r,i,n,s=t.length,a=new Array(2*s);for(e=r=0;e<s;)if((i=t[e++])<128)a[r++]=i;else if(4<(n=u[i]))a[r++]=65533,e+=n-1;else{for(i&=2===n?31:3===n?15:7;1<n&&e<s;)i=i<<6|63&t[e++],n--;1<n?a[r++]=65533:i<65536?a[r++]=i:(i-=65536,a[r++]=55296|i>>10&1023,a[r++]=56320|1023&i)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(t=o.transformTo(h.uint8array?"uint8array":"array",t))},o.inherits(a,i),a.prototype.processChunk=function(t){var e=o.transformTo(h.uint8array?"uint8array":"array",t.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=e;(e=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),e.set(r,this.leftOver.length)}else e=this.leftOver.concat(e);this.leftOver=null}var i=function(t,e){var r;for((e=e||t.length)>t.length&&(e=t.length),r=e-1;0<=r&&128==(192&t[r]);)r--;return r<0?e:0===r?e:r+u[t[r]]>e?r:e}(e),n=e;i!==e.length&&(h.uint8array?(n=e.subarray(0,i),this.leftOver=e.subarray(i,e.length)):(n=e.slice(0,i),this.leftOver=e.slice(i,e.length))),this.push({data:s.utf8decode(n),meta:t.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,i),l.prototype.processChunk=function(t){this.push({data:s.utf8encode(t.data),meta:t.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(t,e,a){"use strict";var o=t("./support"),h=t("./base64"),r=t("./nodejsUtils"),i=t("set-immediate-shim"),u=t("./external");function n(t){return t}function l(t,e){for(var r=0;r<t.length;++r)e[r]=255&t.charCodeAt(r);return e}a.newBlob=function(e,r){a.checkSupport("blob");try{return new Blob([e],{type:r})}catch(t){try{var i=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return i.append(e),i.getBlob(r)}catch(t){throw new Error("Bug : can't construct the Blob.")}}};var s={stringifyByChunk:function(t,e,r){var i=[],n=0,s=t.length;if(s<=r)return String.fromCharCode.apply(null,t);for(;n<s;)"array"===e||"nodebuffer"===e?i.push(String.fromCharCode.apply(null,t.slice(n,Math.min(n+r,s)))):i.push(String.fromCharCode.apply(null,t.subarray(n,Math.min(n+r,s)))),n+=r;return i.join("")},stringifyByChar:function(t){for(var e="",r=0;r<t.length;r++)e+=String.fromCharCode(t[r]);return e},applyCanBeUsed:{uint8array:function(){try{return o.uint8array&&1===String.fromCharCode.apply(null,new Uint8Array(1)).length}catch(t){return!1}}(),nodebuffer:function(){try{return o.nodebuffer&&1===String.fromCharCode.apply(null,r.allocBuffer(1)).length}catch(t){return!1}}()}};function f(t){var e=65536,r=a.getTypeOf(t),i=!0;if("uint8array"===r?i=s.applyCanBeUsed.uint8array:"nodebuffer"===r&&(i=s.applyCanBeUsed.nodebuffer),i)for(;1<e;)try{return s.stringifyByChunk(t,r,e)}catch(t){e=Math.floor(e/2)}return s.stringifyByChar(t)}function d(t,e){for(var r=0;r<t.length;r++)e[r]=t[r];return e}a.applyFromCharCode=f;var c={};c.string={string:n,array:function(t){return l(t,new Array(t.length))},arraybuffer:function(t){return c.string.uint8array(t).buffer},uint8array:function(t){return l(t,new Uint8Array(t.length))},nodebuffer:function(t){return l(t,r.allocBuffer(t.length))}},c.array={string:f,array:n,arraybuffer:function(t){return new Uint8Array(t).buffer},uint8array:function(t){return new Uint8Array(t)},nodebuffer:function(t){return r.newBufferFrom(t)}},c.arraybuffer={string:function(t){return f(new Uint8Array(t))},array:function(t){return d(new Uint8Array(t),new Array(t.byteLength))},arraybuffer:n,uint8array:function(t){return new Uint8Array(t)},nodebuffer:function(t){return r.newBufferFrom(new Uint8Array(t))}},c.uint8array={string:f,array:function(t){return d(t,new Array(t.length))},arraybuffer:function(t){return t.buffer},uint8array:n,nodebuffer:function(t){return r.newBufferFrom(t)}},c.nodebuffer={string:f,array:function(t){return d(t,new Array(t.length))},arraybuffer:function(t){return c.nodebuffer.uint8array(t).buffer},uint8array:function(t){return d(t,new Uint8Array(t.length))},nodebuffer:n},a.transformTo=function(t,e){if(e=e||"",!t)return e;a.checkSupport(t);var r=a.getTypeOf(e);return c[r][t](e)},a.getTypeOf=function(t){return"string"==typeof t?"string":"[object Array]"===Object.prototype.toString.call(t)?"array":o.nodebuffer&&r.isBuffer(t)?"nodebuffer":o.uint8array&&t instanceof Uint8Array?"uint8array":o.arraybuffer&&t instanceof ArrayBuffer?"arraybuffer":void 0},a.checkSupport=function(t){if(!o[t.toLowerCase()])throw new Error(t+" is not supported by this platform")},a.MAX_VALUE_16BITS=65535,a.MAX_VALUE_32BITS=-1,a.pretty=function(t){var e,r,i="";for(r=0;r<(t||"").length;r++)i+="\\x"+((e=t.charCodeAt(r))<16?"0":"")+e.toString(16).toUpperCase();return i},a.delay=function(t,e,r){i(function(){t.apply(r||null,e||[])})},a.inherits=function(t,e){function r(){}r.prototype=e.prototype,t.prototype=new r},a.extend=function(){var t,e,r={};for(t=0;t<arguments.length;t++)for(e in arguments[t])arguments[t].hasOwnProperty(e)&&void 0===r[e]&&(r[e]=arguments[t][e]);return r},a.prepareContent=function(r,t,i,n,s){return u.Promise.resolve(t).then(function(i){return o.blob&&(i instanceof Blob||-1!==["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(i)))&&"undefined"!=typeof FileReader?new u.Promise(function(e,r){var t=new FileReader;t.onload=function(t){e(t.target.result)},t.onerror=function(t){r(t.target.error)},t.readAsArrayBuffer(i)}):i}).then(function(t){var e=a.getTypeOf(t);return e?("arraybuffer"===e?t=a.transformTo("uint8array",t):"string"===e&&(s?t=h.decode(t):i&&!0!==n&&(t=function(t){return l(t,o.uint8array?new Uint8Array(t.length):new Array(t.length))}(t))),t):u.Promise.reject(new Error("Can't read the data of '"+r+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"set-immediate-shim":54}],33:[function(t,e,r){"use strict";var i=t("./reader/readerFor"),n=t("./utils"),s=t("./signature"),a=t("./zipEntry"),o=(t("./utf8"),t("./support"));function h(t){this.files=[],this.loadOptions=t}h.prototype={checkSignature:function(t){if(!this.reader.readAndCheckSignature(t)){this.reader.index-=4;var e=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+n.pretty(e)+", expected "+n.pretty(t)+")")}},isSignature:function(t,e){var r=this.reader.index;this.reader.setIndex(t);var i=this.reader.readString(4)===e;return this.reader.setIndex(r),i},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var t=this.reader.readData(this.zipCommentLength),e=o.uint8array?"uint8array":"array",r=n.transformTo(e,t);this.zipComment=this.loadOptions.decodeFileName(r)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var t,e,r,i=this.zip64EndOfCentralSize-44;0<i;)t=this.reader.readInt(2),e=this.reader.readInt(4),r=this.reader.readData(e),this.zip64ExtensibleData[t]={id:t,length:e,value:r}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),1<this.disksCount)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var t,e;for(t=0;t<this.files.length;t++)e=this.files[t],this.reader.setIndex(e.localHeaderOffset),this.checkSignature(s.LOCAL_FILE_HEADER),e.readLocalPart(this.reader),e.handleUTF8(),e.processAttributes()},readCentralDir:function(){var t;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(s.CENTRAL_FILE_HEADER);)(t=new a({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(t);if(this.centralDirRecords!==this.files.length&&0!==this.centralDirRecords&&0===this.files.length)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var t=this.reader.lastIndexOfSignature(s.CENTRAL_DIRECTORY_END);if(t<0)throw!this.isSignature(0,s.LOCAL_FILE_HEADER)?new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"):new Error("Corrupted zip: can't find end of central directory");this.reader.setIndex(t);var e=t;if(this.checkSignature(s.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===n.MAX_VALUE_16BITS||this.diskWithCentralDirStart===n.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===n.MAX_VALUE_16BITS||this.centralDirRecords===n.MAX_VALUE_16BITS||this.centralDirSize===n.MAX_VALUE_32BITS||this.centralDirOffset===n.MAX_VALUE_32BITS){if(this.zip64=!0,(t=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(t),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,s.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var r=this.centralDirOffset+this.centralDirSize;this.zip64&&(r+=20,r+=12+this.zip64EndOfCentralSize);var i=e-r;if(0<i)this.isSignature(e,s.CENTRAL_FILE_HEADER)||(this.reader.zero=i);else if(i<0)throw new Error("Corrupted zip: missing "+Math.abs(i)+" bytes.")},prepareReader:function(t){this.reader=i(t)},load:function(t){this.prepareReader(t),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},e.exports=h},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(t,e,r){"use strict";var i=t("./reader/readerFor"),s=t("./utils"),n=t("./compressedObject"),a=t("./crc32"),o=t("./utf8"),h=t("./compressions"),u=t("./support");function l(t,e){this.options=t,this.loadOptions=e}l.prototype={isEncrypted:function(){return 1==(1&this.bitFlag)},useUTF8:function(){return 2048==(2048&this.bitFlag)},readLocalPart:function(t){var e,r;if(t.skip(22),this.fileNameLength=t.readInt(2),r=t.readInt(2),this.fileName=t.readData(this.fileNameLength),t.skip(r),-1===this.compressedSize||-1===this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if(null===(e=function(t){for(var e in h)if(h.hasOwnProperty(e)&&h[e].magic===t)return h[e];return null}(this.compressionMethod)))throw new Error("Corrupted zip : compression "+s.pretty(this.compressionMethod)+" unknown (inner file : "+s.transformTo("string",this.fileName)+")");this.decompressed=new n(this.compressedSize,this.uncompressedSize,this.crc32,e,t.readData(this.compressedSize))},readCentralPart:function(t){this.versionMadeBy=t.readInt(2),t.skip(2),this.bitFlag=t.readInt(2),this.compressionMethod=t.readString(2),this.date=t.readDate(),this.crc32=t.readInt(4),this.compressedSize=t.readInt(4),this.uncompressedSize=t.readInt(4);var e=t.readInt(2);if(this.extraFieldsLength=t.readInt(2),this.fileCommentLength=t.readInt(2),this.diskNumberStart=t.readInt(2),this.internalFileAttributes=t.readInt(2),this.externalFileAttributes=t.readInt(4),this.localHeaderOffset=t.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");t.skip(e),this.readExtraFields(t),this.parseZIP64ExtraField(t),this.fileComment=t.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var t=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),0==t&&(this.dosPermissions=63&this.externalFileAttributes),3==t&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(t){if(this.extraFields[1]){var e=i(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(t){var e,r,i,n=t.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});t.index+4<n;)e=t.readInt(2),r=t.readInt(2),i=t.readData(r),this.extraFields[e]={id:e,length:r,value:i};t.setIndex(n)},handleUTF8:function(){var t=u.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=o.utf8decode(this.fileName),this.fileCommentStr=o.utf8decode(this.fileComment);else{var e=this.findExtraFieldUnicodePath();if(null!==e)this.fileNameStr=e;else{var r=s.transformTo(t,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(r)}var i=this.findExtraFieldUnicodeComment();if(null!==i)this.fileCommentStr=i;else{var n=s.transformTo(t,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(n)}}},findExtraFieldUnicodePath:function(){var t=this.extraFields[28789];if(t){var e=i(t.value);return 1!==e.readInt(1)?null:a(this.fileName)!==e.readInt(4)?null:o.utf8decode(e.readData(t.length-5))}return null},findExtraFieldUnicodeComment:function(){var t=this.extraFields[25461];if(t){var e=i(t.value);return 1!==e.readInt(1)?null:a(this.fileComment)!==e.readInt(4)?null:o.utf8decode(e.readData(t.length-5))}return null}},e.exports=l},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(t,e,r){"use strict";function i(t,e,r){this.name=t,this.dir=r.dir,this.date=r.date,this.comment=r.comment,this.unixPermissions=r.unixPermissions,this.dosPermissions=r.dosPermissions,this._data=e,this._dataBinary=r.binary,this.options={compression:r.compression,compressionOptions:r.compressionOptions}}var s=t("./stream/StreamHelper"),n=t("./stream/DataWorker"),a=t("./utf8"),o=t("./compressedObject"),h=t("./stream/GenericWorker");i.prototype={internalStream:function(t){var e=null,r="string";try{if(!t)throw new Error("No output type specified.");var i="string"===(r=t.toLowerCase())||"text"===r;"binarystring"!==r&&"text"!==r||(r="string"),e=this._decompressWorker();var n=!this._dataBinary;n&&!i&&(e=e.pipe(new a.Utf8EncodeWorker)),!n&&i&&(e=e.pipe(new a.Utf8DecodeWorker))}catch(t){(e=new h("error")).error(t)}return new s(e,r,"")},async:function(t,e){return this.internalStream(t).accumulate(e)},nodeStream:function(t,e){return this.internalStream(t||"nodebuffer").toNodejsStream(e)},_compressWorker:function(t,e){if(this._data instanceof o&&this._data.compression.magic===t.magic)return this._data.getCompressedWorker();var r=this._decompressWorker();return this._dataBinary||(r=r.pipe(new a.Utf8EncodeWorker)),o.createWorkerFrom(r,t,e)},_decompressWorker:function(){return this._data instanceof o?this._data.getContentWorker():this._data instanceof h?this._data:new n(this._data)}};for(var u=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],l=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},f=0;f<u.length;f++)i.prototype[u[f]]=l;e.exports=i},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(t,l,e){(function(e){"use strict";var r,i,t=e.MutationObserver||e.WebKitMutationObserver;if(t){var n=0,s=new t(u),a=e.document.createTextNode("");s.observe(a,{characterData:!0}),r=function(){a.data=n=++n%2}}else if(e.setImmediate||void 0===e.MessageChannel)r="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){u(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(u,0)};else{var o=new e.MessageChannel;o.port1.onmessage=u,r=function(){o.port2.postMessage(0)}}var h=[];function u(){var t,e;i=!0;for(var r=h.length;r;){for(e=h,h=[],t=-1;++t<r;)e[t]();r=h.length}i=!1}l.exports=function(t){1!==h.push(t)||i||r()}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],37:[function(t,e,r){"use strict";var n=t("immediate");function u(){}var l={},s=["REJECTED"],a=["FULFILLED"],i=["PENDING"];function o(t){if("function"!=typeof t)throw new TypeError("resolver must be a function");this.state=i,this.queue=[],this.outcome=void 0,t!==u&&c(this,t)}function h(t,e,r){this.promise=t,"function"==typeof e&&(this.onFulfilled=e,this.callFulfilled=this.otherCallFulfilled),"function"==typeof r&&(this.onRejected=r,this.callRejected=this.otherCallRejected)}function f(e,r,i){n(function(){var t;try{t=r(i)}catch(t){return l.reject(e,t)}t===e?l.reject(e,new TypeError("Cannot resolve promise with itself")):l.resolve(e,t)})}function d(t){var e=t&&t.then;if(t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof e)return function(){e.apply(t,arguments)}}function c(e,t){var r=!1;function i(t){r||(r=!0,l.reject(e,t))}function n(t){r||(r=!0,l.resolve(e,t))}var s=p(function(){t(n,i)});"error"===s.status&&i(s.value)}function p(t,e){var r={};try{r.value=t(e),r.status="success"}catch(t){r.status="error",r.value=t}return r}(e.exports=o).prototype.finally=function(e){if("function"!=typeof e)return this;var r=this.constructor;return this.then(function(t){return r.resolve(e()).then(function(){return t})},function(t){return r.resolve(e()).then(function(){throw t})})},o.prototype.catch=function(t){return this.then(null,t)},o.prototype.then=function(t,e){if("function"!=typeof t&&this.state===a||"function"!=typeof e&&this.state===s)return this;var r=new this.constructor(u);this.state!==i?f(r,this.state===a?t:e,this.outcome):this.queue.push(new h(r,t,e));return r},h.prototype.callFulfilled=function(t){l.resolve(this.promise,t)},h.prototype.otherCallFulfilled=function(t){f(this.promise,this.onFulfilled,t)},h.prototype.callRejected=function(t){l.reject(this.promise,t)},h.prototype.otherCallRejected=function(t){f(this.promise,this.onRejected,t)},l.resolve=function(t,e){var r=p(d,e);if("error"===r.status)return l.reject(t,r.value);var i=r.value;if(i)c(t,i);else{t.state=a,t.outcome=e;for(var n=-1,s=t.queue.length;++n<s;)t.queue[n].callFulfilled(e)}return t},l.reject=function(t,e){t.state=s,t.outcome=e;for(var r=-1,i=t.queue.length;++r<i;)t.queue[r].callRejected(e);return t},o.resolve=function(t){if(t instanceof this)return t;return l.resolve(new this(u),t)},o.reject=function(t){var e=new this(u);return l.reject(e,t)},o.all=function(t){var r=this;if("[object Array]"!==Object.prototype.toString.call(t))return this.reject(new TypeError("must be an array"));var i=t.length,n=!1;if(!i)return this.resolve([]);var s=new Array(i),a=0,e=-1,o=new this(u);for(;++e<i;)h(t[e],e);return o;function h(t,e){r.resolve(t).then(function(t){s[e]=t,++a!==i||n||(n=!0,l.resolve(o,s))},function(t){n||(n=!0,l.reject(o,t))})}},o.race=function(t){var e=this;if("[object Array]"!==Object.prototype.toString.call(t))return this.reject(new TypeError("must be an array"));var r=t.length,i=!1;if(!r)return this.resolve([]);var n=-1,s=new this(u);for(;++n<r;)a=t[n],e.resolve(a).then(function(t){i||(i=!0,l.resolve(s,t))},function(t){i||(i=!0,l.reject(s,t))});var a;return s}},{immediate:36}],38:[function(t,e,r){"use strict";var i={};(0,t("./lib/utils/common").assign)(i,t("./lib/deflate"),t("./lib/inflate"),t("./lib/zlib/constants")),e.exports=i},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(t,e,r){"use strict";var a=t("./zlib/deflate"),o=t("./utils/common"),h=t("./utils/strings"),n=t("./zlib/messages"),s=t("./zlib/zstream"),u=Object.prototype.toString,l=0,f=-1,d=0,c=8;function p(t){if(!(this instanceof p))return new p(t);this.options=o.assign({level:f,method:c,chunkSize:16384,windowBits:15,memLevel:8,strategy:d,to:""},t||{});var e=this.options;e.raw&&0<e.windowBits?e.windowBits=-e.windowBits:e.gzip&&0<e.windowBits&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=a.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(r!==l)throw new Error(n[r]);if(e.header&&a.deflateSetHeader(this.strm,e.header),e.dictionary){var i;if(i="string"==typeof e.dictionary?h.string2buf(e.dictionary):"[object ArrayBuffer]"===u.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(r=a.deflateSetDictionary(this.strm,i))!==l)throw new Error(n[r]);this._dict_set=!0}}function i(t,e){var r=new p(e);if(r.push(t,!0),r.err)throw r.msg||n[r.err];return r.result}p.prototype.push=function(t,e){var r,i,n=this.strm,s=this.options.chunkSize;if(this.ended)return!1;i=e===~~e?e:!0===e?4:0,"string"==typeof t?n.input=h.string2buf(t):"[object ArrayBuffer]"===u.call(t)?n.input=new Uint8Array(t):n.input=t,n.next_in=0,n.avail_in=n.input.length;do{if(0===n.avail_out&&(n.output=new o.Buf8(s),n.next_out=0,n.avail_out=s),1!==(r=a.deflate(n,i))&&r!==l)return this.onEnd(r),!(this.ended=!0);0!==n.avail_out&&(0!==n.avail_in||4!==i&&2!==i)||("string"===this.options.to?this.onData(h.buf2binstring(o.shrinkBuf(n.output,n.next_out))):this.onData(o.shrinkBuf(n.output,n.next_out)))}while((0<n.avail_in||0===n.avail_out)&&1!==r);return 4===i?(r=a.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===l):2!==i||(this.onEnd(l),!(n.avail_out=0))},p.prototype.onData=function(t){this.chunks.push(t)},p.prototype.onEnd=function(t){t===l&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},r.Deflate=p,r.deflate=i,r.deflateRaw=function(t,e){return(e=e||{}).raw=!0,i(t,e)},r.gzip=function(t,e){return(e=e||{}).gzip=!0,i(t,e)}},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(t,e,r){"use strict";var d=t("./zlib/inflate"),c=t("./utils/common"),p=t("./utils/strings"),m=t("./zlib/constants"),i=t("./zlib/messages"),n=t("./zlib/zstream"),s=t("./zlib/gzheader"),_=Object.prototype.toString;function a(t){if(!(this instanceof a))return new a(t);this.options=c.assign({chunkSize:16384,windowBits:0,to:""},t||{});var e=this.options;e.raw&&0<=e.windowBits&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(0<=e.windowBits&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),15<e.windowBits&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new n,this.strm.avail_out=0;var r=d.inflateInit2(this.strm,e.windowBits);if(r!==m.Z_OK)throw new Error(i[r]);this.header=new s,d.inflateGetHeader(this.strm,this.header)}function o(t,e){var r=new a(e);if(r.push(t,!0),r.err)throw r.msg||i[r.err];return r.result}a.prototype.push=function(t,e){var r,i,n,s,a,o,h=this.strm,u=this.options.chunkSize,l=this.options.dictionary,f=!1;if(this.ended)return!1;i=e===~~e?e:!0===e?m.Z_FINISH:m.Z_NO_FLUSH,"string"==typeof t?h.input=p.binstring2buf(t):"[object ArrayBuffer]"===_.call(t)?h.input=new Uint8Array(t):h.input=t,h.next_in=0,h.avail_in=h.input.length;do{if(0===h.avail_out&&(h.output=new c.Buf8(u),h.next_out=0,h.avail_out=u),(r=d.inflate(h,m.Z_NO_FLUSH))===m.Z_NEED_DICT&&l&&(o="string"==typeof l?p.string2buf(l):"[object ArrayBuffer]"===_.call(l)?new Uint8Array(l):l,r=d.inflateSetDictionary(this.strm,o)),r===m.Z_BUF_ERROR&&!0===f&&(r=m.Z_OK,f=!1),r!==m.Z_STREAM_END&&r!==m.Z_OK)return this.onEnd(r),!(this.ended=!0);h.next_out&&(0!==h.avail_out&&r!==m.Z_STREAM_END&&(0!==h.avail_in||i!==m.Z_FINISH&&i!==m.Z_SYNC_FLUSH)||("string"===this.options.to?(n=p.utf8border(h.output,h.next_out),s=h.next_out-n,a=p.buf2string(h.output,n),h.next_out=s,h.avail_out=u-s,s&&c.arraySet(h.output,h.output,n,s,0),this.onData(a)):this.onData(c.shrinkBuf(h.output,h.next_out)))),0===h.avail_in&&0===h.avail_out&&(f=!0)}while((0<h.avail_in||0===h.avail_out)&&r!==m.Z_STREAM_END);return r===m.Z_STREAM_END&&(i=m.Z_FINISH),i===m.Z_FINISH?(r=d.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===m.Z_OK):i!==m.Z_SYNC_FLUSH||(this.onEnd(m.Z_OK),!(h.avail_out=0))},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===m.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=c.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},r.Inflate=a,r.inflate=o,r.inflateRaw=function(t,e){return(e=e||{}).raw=!0,o(t,e)},r.ungzip=o},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(t,e,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;r.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var r=e.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)r.hasOwnProperty(i)&&(t[i]=r[i])}}return t},r.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var n={arraySet:function(t,e,r,i,n){if(e.subarray&&t.subarray)t.set(e.subarray(r,r+i),n);else for(var s=0;s<i;s++)t[n+s]=e[r+s]},flattenChunks:function(t){var e,r,i,n,s,a;for(e=i=0,r=t.length;e<r;e++)i+=t[e].length;for(a=new Uint8Array(i),e=n=0,r=t.length;e<r;e++)s=t[e],a.set(s,n),n+=s.length;return a}},s={arraySet:function(t,e,r,i,n){for(var s=0;s<i;s++)t[n+s]=e[r+s]},flattenChunks:function(t){return[].concat.apply([],t)}};r.setTyped=function(t){t?(r.Buf8=Uint8Array,r.Buf16=Uint16Array,r.Buf32=Int32Array,r.assign(r,n)):(r.Buf8=Array,r.Buf16=Array,r.Buf32=Array,r.assign(r,s))},r.setTyped(i)},{}],42:[function(t,e,r){"use strict";var h=t("./common"),n=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){n=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var u=new h.Buf8(256),i=0;i<256;i++)u[i]=252<=i?6:248<=i?5:240<=i?4:224<=i?3:192<=i?2:1;function l(t,e){if(e<65537&&(t.subarray&&s||!t.subarray&&n))return String.fromCharCode.apply(null,h.shrinkBuf(t,e));for(var r="",i=0;i<e;i++)r+=String.fromCharCode(t[i]);return r}u[254]=u[254]=1,r.string2buf=function(t){var e,r,i,n,s,a=t.length,o=0;for(n=0;n<a;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),o+=r<128?1:r<2048?2:r<65536?3:4;for(e=new h.Buf8(o),n=s=0;s<o;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),r<128?e[s++]=r:(r<2048?e[s++]=192|r>>>6:(r<65536?e[s++]=224|r>>>12:(e[s++]=240|r>>>18,e[s++]=128|r>>>12&63),e[s++]=128|r>>>6&63),e[s++]=128|63&r);return e},r.buf2binstring=function(t){return l(t,t.length)},r.binstring2buf=function(t){for(var e=new h.Buf8(t.length),r=0,i=e.length;r<i;r++)e[r]=t.charCodeAt(r);return e},r.buf2string=function(t,e){var r,i,n,s,a=e||t.length,o=new Array(2*a);for(r=i=0;r<a;)if((n=t[r++])<128)o[i++]=n;else if(4<(s=u[n]))o[i++]=65533,r+=s-1;else{for(n&=2===s?31:3===s?15:7;1<s&&r<a;)n=n<<6|63&t[r++],s--;1<s?o[i++]=65533:n<65536?o[i++]=n:(n-=65536,o[i++]=55296|n>>10&1023,o[i++]=56320|1023&n)}return l(o,i)},r.utf8border=function(t,e){var r;for((e=e||t.length)>t.length&&(e=t.length),r=e-1;0<=r&&128==(192&t[r]);)r--;return r<0?e:0===r?e:r+u[t[r]]>e?r:e}},{"./common":41}],43:[function(t,e,r){"use strict";e.exports=function(t,e,r,i){for(var n=65535&t|0,s=t>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3<r?2e3:r;s=s+(n=n+e[i++]|0)|0,--a;);n%=65521,s%=65521}return n|s<<16|0}},{}],44:[function(t,e,r){"use strict";e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],45:[function(t,e,r){"use strict";var o=function(){for(var t,e=[],r=0;r<256;r++){t=r;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[r]=t}return e}();e.exports=function(t,e,r,i){var n=o,s=i+r;t^=-1;for(var a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return-1^t}},{}],46:[function(t,e,r){"use strict";var h,d=t("../utils/common"),u=t("./trees"),c=t("./adler32"),p=t("./crc32"),i=t("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,n=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(t,e){return t.msg=i[e],e}function T(t){return(t<<1)-(4<t?9:0)}function D(t){for(var e=t.length;0<=--e;)t[e]=0}function F(t){var e=t.state,r=e.pending;r>t.avail_out&&(r=t.avail_out),0!==r&&(d.arraySet(t.output,e.pending_buf,e.pending_out,r,t.next_out),t.next_out+=r,e.pending_out+=r,t.total_out+=r,t.avail_out-=r,e.pending-=r,0===e.pending&&(e.pending_out=0))}function N(t,e){u._tr_flush_block(t,0<=t.block_start?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,F(t.strm)}function U(t,e){t.pending_buf[t.pending++]=e}function P(t,e){t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e}function L(t,e){var r,i,n=t.max_chain_length,s=t.strstart,a=t.prev_length,o=t.nice_match,h=t.strstart>t.w_size-z?t.strstart-(t.w_size-z):0,u=t.window,l=t.w_mask,f=t.prev,d=t.strstart+S,c=u[s+a-1],p=u[s+a];t.prev_length>=t.good_match&&(n>>=2),o>t.lookahead&&(o=t.lookahead);do{if(u[(r=e)+a]===p&&u[r+a-1]===c&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&s<d);if(i=S-(d-s),s=d-S,a<i){if(t.match_start=e,o<=(a=i))break;c=u[s+a-1],p=u[s+a]}}}while((e=f[e&l])>h&&0!=--n);return a<=t.lookahead?a:t.lookahead}function j(t){var e,r,i,n,s,a,o,h,u,l,f=t.w_size;do{if(n=t.window_size-t.lookahead-t.strstart,t.strstart>=f+(f-z)){for(d.arraySet(t.window,t.window,f,f,0),t.match_start-=f,t.strstart-=f,t.block_start-=f,e=r=t.hash_size;i=t.head[--e],t.head[e]=f<=i?i-f:0,--r;);for(e=r=f;i=t.prev[--e],t.prev[e]=f<=i?i-f:0,--r;);n+=f}if(0===t.strm.avail_in)break;if(a=t.strm,o=t.window,h=t.strstart+t.lookahead,u=n,l=void 0,l=a.avail_in,u<l&&(l=u),r=0===l?0:(a.avail_in-=l,d.arraySet(o,a.input,a.next_in,l,h),1===a.state.wrap?a.adler=c(a.adler,o,l,h):2===a.state.wrap&&(a.adler=p(a.adler,o,l,h)),a.next_in+=l,a.total_in+=l,l),t.lookahead+=r,t.lookahead+t.insert>=x)for(s=t.strstart-t.insert,t.ins_h=t.window[s],t.ins_h=(t.ins_h<<t.hash_shift^t.window[s+1])&t.hash_mask;t.insert&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[s+x-1])&t.hash_mask,t.prev[s&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=s,s++,t.insert--,!(t.lookahead+t.insert<x)););}while(t.lookahead<z&&0!==t.strm.avail_in)}function Z(t,e){for(var r,i;;){if(t.lookahead<z){if(j(t),t.lookahead<z&&e===l)return A;if(0===t.lookahead)break}if(r=0,t.lookahead>=x&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==r&&t.strstart-r<=t.w_size-z&&(t.match_length=L(t,r)),t.match_length>=x)if(i=u._tr_tally(t,t.strstart-t.match_start,t.match_length-x),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=x){for(t.match_length--;t.strstart++,t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart,0!=--t.match_length;);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+1])&t.hash_mask;else i=u._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=t.strstart<x-1?t.strstart:x-1,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}function W(t,e){for(var r,i,n;;){if(t.lookahead<z){if(j(t),t.lookahead<z&&e===l)return A;if(0===t.lookahead)break}if(r=0,t.lookahead>=x&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=x-1,0!==r&&t.prev_length<t.max_lazy_match&&t.strstart-r<=t.w_size-z&&(t.match_length=L(t,r),t.match_length<=5&&(1===t.strategy||t.match_length===x&&4096<t.strstart-t.match_start)&&(t.match_length=x-1)),t.prev_length>=x&&t.match_length<=t.prev_length){for(n=t.strstart+t.lookahead-x,i=u._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-x),t.lookahead-=t.prev_length-1,t.prev_length-=2;++t.strstart<=n&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!=--t.prev_length;);if(t.match_available=0,t.match_length=x-1,t.strstart++,i&&(N(t,!1),0===t.strm.avail_out))return A}else if(t.match_available){if((i=u._tr_tally(t,0,t.window[t.strstart-1]))&&N(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return A}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=u._tr_tally(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<x-1?t.strstart:x-1,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}function M(t,e,r,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=r,this.max_chain=i,this.func=n}function H(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=v,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new d.Buf16(2*w),this.dyn_dtree=new d.Buf16(2*(2*a+1)),this.bl_tree=new d.Buf16(2*(2*o+1)),D(this.dyn_ltree),D(this.dyn_dtree),D(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new d.Buf16(k+1),this.heap=new d.Buf16(2*s+1),D(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new d.Buf16(2*s+1),D(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function G(t){var e;return t&&t.state?(t.total_in=t.total_out=0,t.data_type=n,(e=t.state).pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?C:E,t.adler=2===e.wrap?0:1,e.last_flush=l,u._tr_init(e),m):R(t,_)}function K(t){var e=G(t);return e===m&&function(t){t.window_size=2*t.w_size,D(t.head),t.max_lazy_match=h[t.level].max_lazy,t.good_match=h[t.level].good_length,t.nice_match=h[t.level].nice_length,t.max_chain_length=h[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=x-1,t.match_available=0,t.ins_h=0}(t.state),e}function Y(t,e,r,i,n,s){if(!t)return _;var a=1;if(e===g&&(e=6),i<0?(a=0,i=-i):15<i&&(a=2,i-=16),n<1||y<n||r!==v||i<8||15<i||e<0||9<e||s<0||b<s)return R(t,_);8===i&&(i=9);var o=new H;return(t.state=o).strm=t,o.wrap=a,o.gzhead=null,o.w_bits=i,o.w_size=1<<o.w_bits,o.w_mask=o.w_size-1,o.hash_bits=n+7,o.hash_size=1<<o.hash_bits,o.hash_mask=o.hash_size-1,o.hash_shift=~~((o.hash_bits+x-1)/x),o.window=new d.Buf8(2*o.w_size),o.head=new d.Buf16(o.hash_size),o.prev=new d.Buf16(o.w_size),o.lit_bufsize=1<<n+6,o.pending_buf_size=4*o.lit_bufsize,o.pending_buf=new d.Buf8(o.pending_buf_size),o.d_buf=1*o.lit_bufsize,o.l_buf=3*o.lit_bufsize,o.level=e,o.strategy=s,o.method=r,K(t)}h=[new M(0,0,0,0,function(t,e){var r=65535;for(r>t.pending_buf_size-5&&(r=t.pending_buf_size-5);;){if(t.lookahead<=1){if(j(t),0===t.lookahead&&e===l)return A;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var i=t.block_start+r;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,N(t,!1),0===t.strm.avail_out))return A;if(t.strstart-t.block_start>=t.w_size-z&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=0,e===f?(N(t,!0),0===t.strm.avail_out?O:B):(t.strstart>t.block_start&&(N(t,!1),t.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(t,e){return Y(t,e,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(t,e){return t&&t.state?2!==t.state.wrap?_:(t.state.gzhead=e,m):_},r.deflate=function(t,e){var r,i,n,s;if(!t||!t.state||5<e||e<0)return t?R(t,_):_;if(i=t.state,!t.output||!t.input&&0!==t.avail_in||666===i.status&&e!==f)return R(t,0===t.avail_out?-5:_);if(i.strm=t,r=i.last_flush,i.last_flush=e,i.status===C)if(2===i.wrap)t.adler=0,U(i,31),U(i,139),U(i,8),i.gzhead?(U(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),U(i,255&i.gzhead.time),U(i,i.gzhead.time>>8&255),U(i,i.gzhead.time>>16&255),U(i,i.gzhead.time>>24&255),U(i,9===i.level?2:2<=i.strategy||i.level<2?4:0),U(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(U(i,255&i.gzhead.extra.length),U(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(t.adler=p(t.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69):(U(i,0),U(i,0),U(i,0),U(i,0),U(i,0),U(i,9===i.level?2:2<=i.strategy||i.level<2?4:0),U(i,3),i.status=E);else{var a=v+(i.w_bits-8<<4)<<8;a|=(2<=i.strategy||i.level<2?0:i.level<6?1:6===i.level?2:3)<<6,0!==i.strstart&&(a|=32),a+=31-a%31,i.status=E,P(i,a),0!==i.strstart&&(P(i,t.adler>>>16),P(i,65535&t.adler)),t.adler=1}if(69===i.status)if(i.gzhead.extra){for(n=i.pending;i.gzindex<(65535&i.gzhead.extra.length)&&(i.pending!==i.pending_buf_size||(i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),F(t),n=i.pending,i.pending!==i.pending_buf_size));)U(i,255&i.gzhead.extra[i.gzindex]),i.gzindex++;i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),i.gzindex===i.gzhead.extra.length&&(i.gzindex=0,i.status=73)}else i.status=73;if(73===i.status)if(i.gzhead.name){n=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),F(t),n=i.pending,i.pending===i.pending_buf_size)){s=1;break}s=i.gzindex<i.gzhead.name.length?255&i.gzhead.name.charCodeAt(i.gzindex++):0,U(i,s)}while(0!==s);i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),0===s&&(i.gzindex=0,i.status=91)}else i.status=91;if(91===i.status)if(i.gzhead.comment){n=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),F(t),n=i.pending,i.pending===i.pending_buf_size)){s=1;break}s=i.gzindex<i.gzhead.comment.length?255&i.gzhead.comment.charCodeAt(i.gzindex++):0,U(i,s)}while(0!==s);i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),0===s&&(i.status=103)}else i.status=103;if(103===i.status&&(i.gzhead.hcrc?(i.pending+2>i.pending_buf_size&&F(t),i.pending+2<=i.pending_buf_size&&(U(i,255&t.adler),U(i,t.adler>>8&255),t.adler=0,i.status=E)):i.status=E),0!==i.pending){if(F(t),0===t.avail_out)return i.last_flush=-1,m}else if(0===t.avail_in&&T(e)<=T(r)&&e!==f)return R(t,-5);if(666===i.status&&0!==t.avail_in)return R(t,-5);if(0!==t.avail_in||0!==i.lookahead||e!==l&&666!==i.status){var o=2===i.strategy?function(t,e){for(var r;;){if(0===t.lookahead&&(j(t),0===t.lookahead)){if(e===l)return A;break}if(t.match_length=0,r=u._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,r&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=0,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}(i,e):3===i.strategy?function(t,e){for(var r,i,n,s,a=t.window;;){if(t.lookahead<=S){if(j(t),t.lookahead<=S&&e===l)return A;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=x&&0<t.strstart&&(i=a[n=t.strstart-1])===a[++n]&&i===a[++n]&&i===a[++n]){s=t.strstart+S;do{}while(i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&n<s);t.match_length=S-(s-n),t.match_length>t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=x?(r=u._tr_tally(t,1,t.match_length-x),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(r=u._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),r&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=0,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}(i,e):h[i.level].func(i,e);if(o!==O&&o!==B||(i.status=666),o===A||o===O)return 0===t.avail_out&&(i.last_flush=-1),m;if(o===I&&(1===e?u._tr_align(i):5!==e&&(u._tr_stored_block(i,0,0,!1),3===e&&(D(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),F(t),0===t.avail_out))return i.last_flush=-1,m}return e!==f?m:i.wrap<=0?1:(2===i.wrap?(U(i,255&t.adler),U(i,t.adler>>8&255),U(i,t.adler>>16&255),U(i,t.adler>>24&255),U(i,255&t.total_in),U(i,t.total_in>>8&255),U(i,t.total_in>>16&255),U(i,t.total_in>>24&255)):(P(i,t.adler>>>16),P(i,65535&t.adler)),F(t),0<i.wrap&&(i.wrap=-i.wrap),0!==i.pending?m:1)},r.deflateEnd=function(t){var e;return t&&t.state?(e=t.state.status)!==C&&69!==e&&73!==e&&91!==e&&103!==e&&e!==E&&666!==e?R(t,_):(t.state=null,e===E?R(t,-3):m):_},r.deflateSetDictionary=function(t,e){var r,i,n,s,a,o,h,u,l=e.length;if(!t||!t.state)return _;if(2===(s=(r=t.state).wrap)||1===s&&r.status!==C||r.lookahead)return _;for(1===s&&(t.adler=c(t.adler,e,l,0)),r.wrap=0,l>=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new d.Buf8(r.w_size),d.arraySet(u,e,l-r.w_size,r.w_size,0),e=u,l=r.w_size),a=t.avail_in,o=t.next_in,h=t.input,t.avail_in=l,t.next_in=0,t.input=e,j(r);r.lookahead>=x;){for(i=r.strstart,n=r.lookahead-(x-1);r.ins_h=(r.ins_h<<r.hash_shift^r.window[i+x-1])&r.hash_mask,r.prev[i&r.w_mask]=r.head[r.ins_h],r.head[r.ins_h]=i,i++,--n;);r.strstart=i,r.lookahead=x-1,j(r)}return r.strstart+=r.lookahead,r.block_start=r.strstart,r.insert=r.lookahead,r.lookahead=0,r.match_length=r.prev_length=x-1,r.match_available=0,t.next_in=o,t.input=h,t.avail_in=a,r.wrap=s,m},r.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(t,e,r){"use strict";e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],48:[function(t,e,r){"use strict";e.exports=function(t,e){var r,i,n,s,a,o,h,u,l,f,d,c,p,m,_,g,b,v,y,w,k,x,S,z,C;r=t.state,i=t.next_in,z=t.input,n=i+(t.avail_in-5),s=t.next_out,C=t.output,a=s-(e-t.avail_out),o=s+(t.avail_out-257),h=r.dmax,u=r.wsize,l=r.whave,f=r.wnext,d=r.window,c=r.hold,p=r.bits,m=r.lencode,_=r.distcode,g=(1<<r.lenbits)-1,b=(1<<r.distbits)-1;t:do{p<15&&(c+=z[i++]<<p,p+=8,c+=z[i++]<<p,p+=8),v=m[c&g];e:for(;;){if(c>>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(c&(1<<y)-1)];continue e}if(32&y){r.mode=12;break t}t.msg="invalid literal/length code",r.mode=30;break t}w=65535&v,(y&=15)&&(p<y&&(c+=z[i++]<<p,p+=8),w+=c&(1<<y)-1,c>>>=y,p-=y),p<15&&(c+=z[i++]<<p,p+=8,c+=z[i++]<<p,p+=8),v=_[c&b];r:for(;;){if(c>>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(c&(1<<y)-1)];continue r}t.msg="invalid distance code",r.mode=30;break t}if(k=65535&v,p<(y&=15)&&(c+=z[i++]<<p,(p+=8)<y&&(c+=z[i++]<<p,p+=8)),h<(k+=c&(1<<y)-1)){t.msg="invalid distance too far back",r.mode=30;break t}if(c>>>=y,p-=y,(y=s-a)<k){if(l<(y=k-y)&&r.sane){t.msg="invalid distance too far back",r.mode=30;break t}if(S=d,(x=0)===f){if(x+=u-y,y<w){for(w-=y;C[s++]=d[x++],--y;);x=s-k,S=C}}else if(f<y){if(x+=u+f-y,(y-=f)<w){for(w-=y;C[s++]=d[x++],--y;);if(x=0,f<w){for(w-=y=f;C[s++]=d[x++],--y;);x=s-k,S=C}}}else if(x+=f-y,y<w){for(w-=y;C[s++]=d[x++],--y;);x=s-k,S=C}for(;2<w;)C[s++]=S[x++],C[s++]=S[x++],C[s++]=S[x++],w-=3;w&&(C[s++]=S[x++],1<w&&(C[s++]=S[x++]))}else{for(x=s-k;C[s++]=C[x++],C[s++]=C[x++],C[s++]=C[x++],2<(w-=3););w&&(C[s++]=C[x++],1<w&&(C[s++]=C[x++]))}break}}break}}while(i<n&&s<o);i-=w=p>>3,c&=(1<<(p-=w<<3))-1,t.next_in=i,t.next_out=s,t.avail_in=i<n?n-i+5:5-(i-n),t.avail_out=s<o?o-s+257:257-(s-o),r.hold=c,r.bits=p}},{}],49:[function(t,e,r){"use strict";var I=t("../utils/common"),O=t("./adler32"),B=t("./crc32"),R=t("./inffast"),T=t("./inftrees"),D=1,F=2,N=0,U=-2,P=1,i=852,n=592;function L(t){return(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=P,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new I.Buf32(i),e.distcode=e.distdyn=new I.Buf32(n),e.sane=1,e.back=-1,N):U}function o(t){var e;return t&&t.state?((e=t.state).wsize=0,e.whave=0,e.wnext=0,a(t)):U}function h(t,e){var r,i;return t&&t.state?(i=t.state,e<0?(r=0,e=-e):(r=1+(e>>4),e<48&&(e&=15)),e&&(e<8||15<e)?U:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=r,i.wbits=e,o(t))):U}function u(t,e){var r,i;return t?(i=new s,(t.state=i).window=null,(r=h(t,e))!==N&&(t.state=null),r):U}var l,f,d=!0;function j(t){if(d){var e;for(l=new I.Buf32(512),f=new I.Buf32(32),e=0;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(T(D,t.lens,0,288,l,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;T(F,t.lens,0,32,f,0,t.work,{bits:5}),d=!1}t.lencode=l,t.lenbits=9,t.distcode=f,t.distbits=5}function Z(t,e,r,i){var n,s=t.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new I.Buf8(s.wsize)),i>=s.wsize?(I.arraySet(s.window,e,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(i<(n=s.wsize-s.wnext)&&(n=i),I.arraySet(s.window,e,r-i,n,s.wnext),(i-=n)?(I.arraySet(s.window,e,r-i,i,0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=n))),0}r.inflateReset=o,r.inflateReset2=h,r.inflateResetKeep=a,r.inflateInit=function(t){return u(t,15)},r.inflateInit2=u,r.inflate=function(t,e){var r,i,n,s,a,o,h,u,l,f,d,c,p,m,_,g,b,v,y,w,k,x,S,z,C=0,E=new I.Buf8(4),A=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return U;12===(r=t.state).mode&&(r.mode=13),a=t.next_out,n=t.output,h=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,u=r.hold,l=r.bits,f=o,d=h,x=N;t:for(;;)switch(r.mode){case P:if(0===r.wrap){r.mode=13;break}for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(2&r.wrap&&35615===u){E[r.check=0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){t.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){t.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){t.msg="invalid window size",r.mode=30;break}r.dmax=1<<k,t.adler=r.check=1,r.mode=512&u?10:12,l=u=0;break;case 2:for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(r.flags=u,8!=(255&r.flags)){t.msg="unknown compression method",r.mode=30;break}if(57344&r.flags){t.msg="unknown header flags set",r.mode=30;break}r.head&&(r.head.text=u>>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.head&&(r.head.time=u),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.head&&(r.head.xflags=255&u,r.head.os=u>>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.length=u,r.head&&(r.head.extra_len=u),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(c=r.length)&&(c=o),c&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,i,s,c,k)),512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,r.length-=c),r.length))break t;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break t;for(c=0;k=i[s+c++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&c<o;);if(512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,k)break t}else r.head&&(r.head.name=null);r.length=0,r.mode=8;case 8:if(4096&r.flags){if(0===o)break t;for(c=0;k=i[s+c++],r.head&&k&&r.length<65536&&(r.head.comment+=String.fromCharCode(k)),k&&c<o;);if(512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,k)break t}else r.head&&(r.head.comment=null);r.mode=9;case 9:if(512&r.flags){for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(u!==(65535&r.check)){t.msg="header crc mismatch",r.mode=30;break}l=u=0}r.head&&(r.head.hcrc=r.flags>>9&1,r.head.done=!0),t.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}t.adler=r.check=L(u),l=u=0,r.mode=11;case 11:if(0===r.havedict)return t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,2;t.adler=r.check=1,r.mode=12;case 12:if(5===e||6===e)break t;case 13:if(r.last){u>>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}switch(r.last=1&u,l-=1,3&(u>>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==e)break;u>>>=2,l-=2;break t;case 2:r.mode=17;break;case 3:t.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if((65535&u)!=(u>>>16^65535)){t.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===e)break t;case 15:r.mode=16;case 16:if(c=r.length){if(o<c&&(c=o),h<c&&(c=h),0===c)break t;I.arraySet(n,i,s,c,a),o-=c,s+=c,h-=c,a+=c,r.length-=c;break}r.mode=12;break;case 17:for(;l<14;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(r.nlen=257+(31&u),u>>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286<r.nlen||30<r.ndist){t.msg="too many length or distance symbols",r.mode=30;break}r.have=0,r.mode=18;case 18:for(;r.have<r.ncode;){for(;l<3;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.lens[A[r.have++]]=7&u,u>>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){t.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have<r.nlen+r.ndist;){for(;g=(C=r.lencode[u&(1<<r.lenbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(b<16)u>>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(u>>>=_,l-=_,0===r.have){t.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],c=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}l-=_,k=0,c=3+(7&(u>>>=_)),u>>>=3,l-=3}else{for(z=_+7;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}l-=_,k=0,c=11+(127&(u>>>=_)),u>>>=7,l-=7}if(r.have+c>r.nlen+r.ndist){t.msg="invalid bit length repeat",r.mode=30;break}for(;c--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){t.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){t.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){t.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===e)break t;case 20:r.mode=21;case 21:if(6<=o&&258<=h){t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,R(t,d),a=t.next_out,n=t.output,h=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<<r.lenbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(g&&0==(240&g)){for(v=_,y=g,w=b;g=(C=r.lencode[w+((u&(1<<v+y)-1)>>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}u>>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){t.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.length+=u&(1<<r.extra)-1,u>>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<<r.distbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(0==(240&g)){for(v=_,y=g,w=b;g=(C=r.distcode[w+((u&(1<<v+y)-1)>>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}u>>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){t.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.offset+=u&(1<<r.extra)-1,u>>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){t.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break t;if(c=d-h,r.offset>c){if((c=r.offset-c)>r.whave&&r.sane){t.msg="invalid distance too far back",r.mode=30;break}p=c>r.wnext?(c-=r.wnext,r.wsize-c):r.wnext-c,c>r.length&&(c=r.length),m=r.window}else m=n,p=a-r.offset,c=r.length;for(h<c&&(c=h),h-=c,r.length-=c;n[a++]=m[p++],--c;);0===r.length&&(r.mode=21);break;case 26:if(0===h)break t;n[a++]=r.length,h--,r.mode=21;break;case 27:if(r.wrap){for(;l<32;){if(0===o)break t;o--,u|=i[s++]<<l,l+=8}if(d-=h,t.total_out+=d,r.total+=d,d&&(t.adler=r.check=r.flags?B(r.check,n,d,a-d):O(r.check,n,d,a-d)),d=h,(r.flags?u:L(u))!==r.check){t.msg="incorrect data check",r.mode=30;break}l=u=0}r.mode=28;case 28:if(r.wrap&&r.flags){for(;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(u!==(4294967295&r.total)){t.msg="incorrect length check",r.mode=30;break}l=u=0}r.mode=29;case 29:x=1;break t;case 30:x=-3;break t;case 31:return-4;case 32:default:return U}return t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,(r.wsize||d!==t.avail_out&&r.mode<30&&(r.mode<27||4!==e))&&Z(t,t.output,t.next_out,d-t.avail_out)?(r.mode=31,-4):(f-=t.avail_in,d-=t.avail_out,t.total_in+=f,t.total_out+=d,r.total+=d,r.wrap&&d&&(t.adler=r.check=r.flags?B(r.check,n,d,t.next_out-d):O(r.check,n,d,t.next_out-d)),t.data_type=r.bits+(r.last?64:0)+(12===r.mode?128:0)+(20===r.mode||15===r.mode?256:0),(0==f&&0===d||4===e)&&x===N&&(x=-5),x)},r.inflateEnd=function(t){if(!t||!t.state)return U;var e=t.state;return e.window&&(e.window=null),t.state=null,N},r.inflateGetHeader=function(t,e){var r;return t&&t.state?0==(2&(r=t.state).wrap)?U:((r.head=e).done=!1,N):U},r.inflateSetDictionary=function(t,e){var r,i=e.length;return t&&t.state?0!==(r=t.state).wrap&&11!==r.mode?U:11===r.mode&&O(1,e,i,0)!==r.check?-3:Z(t,e,i,i)?(r.mode=31,-4):(r.havedict=1,N):U},r.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(t,e,r){"use strict";var D=t("../utils/common"),F=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],N=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],U=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],P=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(t,e,r,i,n,s,a,o){var h,u,l,f,d,c,p,m,_,g=o.bits,b=0,v=0,y=0,w=0,k=0,x=0,S=0,z=0,C=0,E=0,A=null,I=0,O=new D.Buf16(16),B=new D.Buf16(16),R=null,T=0;for(b=0;b<=15;b++)O[b]=0;for(v=0;v<i;v++)O[e[r+v]]++;for(k=g,w=15;1<=w&&0===O[w];w--);if(w<k&&(k=w),0===w)return n[s++]=20971520,n[s++]=20971520,o.bits=1,0;for(y=1;y<w&&0===O[y];y++);for(k<y&&(k=y),b=z=1;b<=15;b++)if(z<<=1,(z-=O[b])<0)return-1;if(0<z&&(0===t||1!==w))return-1;for(B[1]=0,b=1;b<15;b++)B[b+1]=B[b]+O[b];for(v=0;v<i;v++)0!==e[r+v]&&(a[B[e[r+v]]++]=v);if(c=0===t?(A=R=a,19):1===t?(A=F,I-=257,R=N,T-=257,256):(A=U,R=P,-1),b=y,d=s,S=v=E=0,l=-1,f=(C=1<<(x=k))-1,1===t&&852<C||2===t&&592<C)return 1;for(;;){for(p=b-S,_=a[v]<c?(m=0,a[v]):a[v]>c?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<<b-S,y=u=1<<x;n[d+(E>>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<<b-1;E&h;)h>>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=e[r+a[v]]}if(k<b&&(E&f)!==l){for(0===S&&(S=k),d+=y,z=1<<(x=b-S);x+S<w&&!((z-=O[x+S])<=0);)x++,z<<=1;if(C+=1<<x,1===t&&852<C||2===t&&592<C)return 1;n[l=E&f]=k<<24|x<<16|d-s|0}}return 0!==E&&(n[d+E]=b-S<<24|64<<16|0),o.bits=k,0}},{"../utils/common":41}],51:[function(t,e,r){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],52:[function(t,e,r){"use strict";var n=t("../utils/common"),o=0,h=1;function i(t){for(var e=t.length;0<=--e;)t[e]=0}var s=0,a=29,u=256,l=u+1+a,f=30,d=19,_=2*l+1,g=15,c=16,p=7,m=256,b=16,v=17,y=18,w=[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],k=[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],x=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],z=new Array(2*(l+2));i(z);var C=new Array(2*f);i(C);var E=new Array(512);i(E);var A=new Array(256);i(A);var I=new Array(a);i(I);var O,B,R,T=new Array(f);function D(t,e,r,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=r,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}function F(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}function N(t){return t<256?E[t]:E[256+(t>>>7)]}function U(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function P(t,e,r){t.bi_valid>c-r?(t.bi_buf|=e<<t.bi_valid&65535,U(t,t.bi_buf),t.bi_buf=e>>c-t.bi_valid,t.bi_valid+=r-c):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=r)}function L(t,e,r){P(t,r[2*e],r[2*e+1])}function j(t,e){for(var r=0;r|=1&t,t>>>=1,r<<=1,0<--e;);return r>>>1}function Z(t,e,r){var i,n,s=new Array(g+1),a=0;for(i=1;i<=g;i++)s[i]=a=a+r[i-1]<<1;for(n=0;n<=e;n++){var o=t[2*n+1];0!==o&&(t[2*n]=j(s[o]++,o))}}function W(t){var e;for(e=0;e<l;e++)t.dyn_ltree[2*e]=0;for(e=0;e<f;e++)t.dyn_dtree[2*e]=0;for(e=0;e<d;e++)t.bl_tree[2*e]=0;t.dyn_ltree[2*m]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function M(t){8<t.bi_valid?U(t,t.bi_buf):0<t.bi_valid&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0}function H(t,e,r,i){var n=2*e,s=2*r;return t[n]<t[s]||t[n]===t[s]&&i[e]<=i[r]}function G(t,e,r){for(var i=t.heap[r],n=r<<1;n<=t.heap_len&&(n<t.heap_len&&H(e,t.heap[n+1],t.heap[n],t.depth)&&n++,!H(e,i,t.heap[n],t.depth));)t.heap[r]=t.heap[n],r=n,n<<=1;t.heap[r]=i}function K(t,e,r){var i,n,s,a,o=0;if(0!==t.last_lit)for(;i=t.pending_buf[t.d_buf+2*o]<<8|t.pending_buf[t.d_buf+2*o+1],n=t.pending_buf[t.l_buf+o],o++,0===i?L(t,n,e):(L(t,(s=A[n])+u+1,e),0!==(a=w[s])&&P(t,n-=I[s],a),L(t,s=N(--i),r),0!==(a=k[s])&&P(t,i-=T[s],a)),o<t.last_lit;);L(t,m,e)}function Y(t,e){var r,i,n,s=e.dyn_tree,a=e.stat_desc.static_tree,o=e.stat_desc.has_stree,h=e.stat_desc.elems,u=-1;for(t.heap_len=0,t.heap_max=_,r=0;r<h;r++)0!==s[2*r]?(t.heap[++t.heap_len]=u=r,t.depth[r]=0):s[2*r+1]=0;for(;t.heap_len<2;)s[2*(n=t.heap[++t.heap_len]=u<2?++u:0)]=1,t.depth[n]=0,t.opt_len--,o&&(t.static_len-=a[2*n+1]);for(e.max_code=u,r=t.heap_len>>1;1<=r;r--)G(t,s,r);for(n=h;r=t.heap[1],t.heap[1]=t.heap[t.heap_len--],G(t,s,1),i=t.heap[1],t.heap[--t.heap_max]=r,t.heap[--t.heap_max]=i,s[2*n]=s[2*r]+s[2*i],t.depth[n]=(t.depth[r]>=t.depth[i]?t.depth[r]:t.depth[i])+1,s[2*r+1]=s[2*i+1]=n,t.heap[1]=n++,G(t,s,1),2<=t.heap_len;);t.heap[--t.heap_max]=t.heap[1],function(t,e){var r,i,n,s,a,o,h=e.dyn_tree,u=e.max_code,l=e.stat_desc.static_tree,f=e.stat_desc.has_stree,d=e.stat_desc.extra_bits,c=e.stat_desc.extra_base,p=e.stat_desc.max_length,m=0;for(s=0;s<=g;s++)t.bl_count[s]=0;for(h[2*t.heap[t.heap_max]+1]=0,r=t.heap_max+1;r<_;r++)p<(s=h[2*h[2*(i=t.heap[r])+1]+1]+1)&&(s=p,m++),h[2*i+1]=s,u<i||(t.bl_count[s]++,a=0,c<=i&&(a=d[i-c]),o=h[2*i],t.opt_len+=o*(s+a),f&&(t.static_len+=o*(l[2*i+1]+a)));if(0!==m){do{for(s=p-1;0===t.bl_count[s];)s--;t.bl_count[s]--,t.bl_count[s+1]+=2,t.bl_count[p]--,m-=2}while(0<m);for(s=p;0!==s;s--)for(i=t.bl_count[s];0!==i;)u<(n=t.heap[--r])||(h[2*n+1]!==s&&(t.opt_len+=(s-h[2*n+1])*h[2*n],h[2*n+1]=s),i--)}}(t,e),Z(s,u,t.bl_count)}function X(t,e,r){var i,n,s=-1,a=e[1],o=0,h=7,u=4;for(0===a&&(h=138,u=3),e[2*(r+1)+1]=65535,i=0;i<=r;i++)n=a,a=e[2*(i+1)+1],++o<h&&n===a||(o<u?t.bl_tree[2*n]+=o:0!==n?(n!==s&&t.bl_tree[2*n]++,t.bl_tree[2*b]++):o<=10?t.bl_tree[2*v]++:t.bl_tree[2*y]++,s=n,u=(o=0)===a?(h=138,3):n===a?(h=6,3):(h=7,4))}function V(t,e,r){var i,n,s=-1,a=e[1],o=0,h=7,u=4;for(0===a&&(h=138,u=3),i=0;i<=r;i++)if(n=a,a=e[2*(i+1)+1],!(++o<h&&n===a)){if(o<u)for(;L(t,n,t.bl_tree),0!=--o;);else 0!==n?(n!==s&&(L(t,n,t.bl_tree),o--),L(t,b,t.bl_tree),P(t,o-3,2)):o<=10?(L(t,v,t.bl_tree),P(t,o-3,3)):(L(t,y,t.bl_tree),P(t,o-11,7));s=n,u=(o=0)===a?(h=138,3):n===a?(h=6,3):(h=7,4)}}i(T);var q=!1;function J(t,e,r,i){P(t,(s<<1)+(i?1:0),3),function(t,e,r,i){M(t),i&&(U(t,r),U(t,~r)),n.arraySet(t.pending_buf,t.window,e,r,t.pending),t.pending+=r}(t,e,r,!0)}r._tr_init=function(t){q||(function(){var t,e,r,i,n,s=new Array(g+1);for(i=r=0;i<a-1;i++)for(I[i]=r,t=0;t<1<<w[i];t++)A[r++]=i;for(A[r-1]=i,i=n=0;i<16;i++)for(T[i]=n,t=0;t<1<<k[i];t++)E[n++]=i;for(n>>=7;i<f;i++)for(T[i]=n<<7,t=0;t<1<<k[i]-7;t++)E[256+n++]=i;for(e=0;e<=g;e++)s[e]=0;for(t=0;t<=143;)z[2*t+1]=8,t++,s[8]++;for(;t<=255;)z[2*t+1]=9,t++,s[9]++;for(;t<=279;)z[2*t+1]=7,t++,s[7]++;for(;t<=287;)z[2*t+1]=8,t++,s[8]++;for(Z(z,l+1,s),t=0;t<f;t++)C[2*t+1]=5,C[2*t]=j(t,5);O=new D(z,w,u+1,l,g),B=new D(C,k,0,f,g),R=new D(new Array(0),x,0,d,p)}(),q=!0),t.l_desc=new F(t.dyn_ltree,O),t.d_desc=new F(t.dyn_dtree,B),t.bl_desc=new F(t.bl_tree,R),t.bi_buf=0,t.bi_valid=0,W(t)},r._tr_stored_block=J,r._tr_flush_block=function(t,e,r,i){var n,s,a=0;0<t.level?(2===t.strm.data_type&&(t.strm.data_type=function(t){var e,r=4093624447;for(e=0;e<=31;e++,r>>>=1)if(1&r&&0!==t.dyn_ltree[2*e])return o;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return h;for(e=32;e<u;e++)if(0!==t.dyn_ltree[2*e])return h;return o}(t)),Y(t,t.l_desc),Y(t,t.d_desc),a=function(t){var e;for(X(t,t.dyn_ltree,t.l_desc.max_code),X(t,t.dyn_dtree,t.d_desc.max_code),Y(t,t.bl_desc),e=d-1;3<=e&&0===t.bl_tree[2*S[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}(t),n=t.opt_len+3+7>>>3,(s=t.static_len+3+7>>>3)<=n&&(n=s)):n=s=r+5,r+4<=n&&-1!==e?J(t,e,r,i):4===t.strategy||s===n?(P(t,2+(i?1:0),3),K(t,z,C)):(P(t,4+(i?1:0),3),function(t,e,r,i){var n;for(P(t,e-257,5),P(t,r-1,5),P(t,i-4,4),n=0;n<i;n++)P(t,t.bl_tree[2*S[n]+1],3);V(t,t.dyn_ltree,e-1),V(t,t.dyn_dtree,r-1)}(t,t.l_desc.max_code+1,t.d_desc.max_code+1,a+1),K(t,t.dyn_ltree,t.dyn_dtree)),W(t),i&&M(t)},r._tr_tally=function(t,e,r){return t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&r,t.last_lit++,0===e?t.dyn_ltree[2*r]++:(t.matches++,e--,t.dyn_ltree[2*(A[r]+u+1)]++,t.dyn_dtree[2*N(e)]++),t.last_lit===t.lit_bufsize-1},r._tr_align=function(t){P(t,2,3),L(t,m,z),function(t){16===t.bi_valid?(U(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):8<=t.bi_valid&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}(t)}},{"../utils/common":41}],53:[function(t,e,r){"use strict";e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(t,e,r){"use strict";e.exports="function"==typeof setImmediate?setImmediate:function(){var t=[].slice.apply(arguments);t.splice(1,0,0),setTimeout.apply(null,t)}},{}]},{},[10])(10)});
32400/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(17).Buffer, __webpack_require__(2), __webpack_require__(21).setImmediate))
32401
32402/***/ }),
32403/* 17 */
32404/***/ (function(module, exports, __webpack_require__) {
32405
32406"use strict";
32407/* WEBPACK VAR INJECTION */(function(global) {/*!
32408 * The buffer module from node.js, for the browser.
32409 *
32410 * @author   Feross Aboukhadijeh <http://feross.org>
32411 * @license  MIT
32412 */
32413/* eslint-disable no-proto */
32414
32415
32416
32417var base64 = __webpack_require__(18)
32418var ieee754 = __webpack_require__(19)
32419var isArray = __webpack_require__(20
vendor: 48,375 bytes, lines 32419-34197
32419)
32420
32421exports.Buffer = Buffer
32422exports.SlowBuffer = SlowBuffer
32423exports.INSPECT_MAX_BYTES = 50
32424
32425/**
32426 * If `Buffer.TYPED_ARRAY_SUPPORT`:
32427 *   === true    Use Uint8Array implementation (fastest)
32428 *   === false   Use Object implementation (most compatible, even IE6)
32429 *
32430 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
32431 * Opera 11.6+, iOS 4.2+.
32432 *
32433 * Due to various browser bugs, sometimes the Object implementation will be used even
32434 * when the browser supports typed arrays.
32435 *
32436 * Note:
32437 *
32438 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
32439 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
32440 *
32441 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
32442 *
32443 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
32444 *     incorrect length in some situations.
32445
32446 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
32447 * get the Object implementation, which is slower but behaves correctly.
32448 */
32449Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
32450  ? global.TYPED_ARRAY_SUPPORT
32451  : typedArraySupport()
32452
32453/*
32454 * Export kMaxLength after typed array support is determined.
32455 */
32456exports.kMaxLength = kMaxLength()
32457
32458function typedArraySupport () {
32459  try {
32460    var arr = new Uint8Array(1)
32461    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
32462    return arr.foo() === 42 && // typed array instances can be augmented
32463        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
32464        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
32465  } catch (e) {
32466    return false
32467  }
32468}
32469
32470function kMaxLength () {
32471  return Buffer.TYPED_ARRAY_SUPPORT
32472    ? 0x7fffffff
32473    : 0x3fffffff
32474}
32475
32476function createBuffer (that, length) {
32477  if (kMaxLength() < length) {
32478    throw new RangeError('Invalid typed array length')
32479  }
32480  if (Buffer.TYPED_ARRAY_SUPPORT) {
32481    // Return an augmented `Uint8Array` instance, for best performance
32482    that = new Uint8Array(length)
32483    that.__proto__ = Buffer.prototype
32484  } else {
32485    // Fallback: Return an object instance of the Buffer class
32486    if (that === null) {
32487      that = new Buffer(length)
32488    }
32489    that.length = length
32490  }
32491
32492  return that
32493}
32494
32495/**
32496 * The Buffer constructor returns instances of `Uint8Array` that have their
32497 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
32498 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
32499 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
32500 * returns a single octet.
32501 *
32502 * The `Uint8Array` prototype remains unmodified.
32503 */
32504
32505function Buffer (arg, encodingOrOffset, length) {
32506  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
32507    return new Buffer(arg, encodingOrOffset, length)
32508  }
32509
32510  // Common case.
32511  if (typeof arg === 'number') {
32512    if (typeof encodingOrOffset === 'string') {
32513      throw new Error(
32514        'If encoding is specified then the first argument must be a string'
32515      )
32516    }
32517    return allocUnsafe(this, arg)
32518  }
32519  return from(this, arg, encodingOrOffset, length)
32520}
32521
32522Buffer.poolSize = 8192 // not used by this implementation
32523
32524// TODO: Legacy, not needed anymore. Remove in next major version.
32525Buffer._augment = function (arr) {
32526  arr.__proto__ = Buffer.prototype
32527  return arr
32528}
32529
32530function from (that, value, encodingOrOffset, length) {
32531  if (typeof value === 'number') {
32532    throw new TypeError('"value" argument must not be a number')
32533  }
32534
32535  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
32536    return fromArrayBuffer(that, value, encodingOrOffset, length)
32537  }
32538
32539  if (typeof value === 'string') {
32540    return fromString(that, value, encodingOrOffset)
32541  }
32542
32543  return fromObject(that, value)
32544}
32545
32546/**
32547 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
32548 * if value is a number.
32549 * Buffer.from(str[, encoding])
32550 * Buffer.from(array)
32551 * Buffer.from(buffer)
32552 * Buffer.from(arrayBuffer[, byteOffset[, length]])
32553 **/
32554Buffer.from = function (value, encodingOrOffset, length) {
32555  return from(null, value, encodingOrOffset, length)
32556}
32557
32558if (Buffer.TYPED_ARRAY_SUPPORT) {
32559  Buffer.prototype.__proto__ = Uint8Array.prototype
32560  Buffer.__proto__ = Uint8Array
32561  if (typeof Symbol !== 'undefined' && Symbol.species &&
32562      Buffer[Symbol.species] === Buffer) {
32563    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
32564    Object.defineProperty(Buffer, Symbol.species, {
32565      value: null,
32566      configurable: true
32567    })
32568  }
32569}
32570
32571function assertSize (size) {
32572  if (typeof size !== 'number') {
32573    throw new TypeError('"size" argument must be a number')
32574  } else if (size < 0) {
32575    throw new RangeError('"size" argument must not be negative')
32576  }
32577}
32578
32579function alloc (that, size, fill, encoding) {
32580  assertSize(size)
32581  if (size <= 0) {
32582    return createBuffer(that, size)
32583  }
32584  if (fill !== undefined) {
32585    // Only pay attention to encoding if it's a string. This
32586    // prevents accidentally sending in a number that would
32587    // be interpretted as a start offset.
32588    return typeof encoding === 'string'
32589      ? createBuffer(that, size).fill(fill, encoding)
32590      : createBuffer(that, size).fill(fill)
32591  }
32592  return createBuffer(that, size)
32593}
32594
32595/**
32596 * Creates a new filled Buffer instance.
32597 * alloc(size[, fill[, encoding]])
32598 **/
32599Buffer.alloc = function (size, fill, encoding) {
32600  return alloc(null, size, fill, encoding)
32601}
32602
32603function allocUnsafe (that, size) {
32604  assertSize(size)
32605  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
32606  if (!Buffer.TYPED_ARRAY_SUPPORT) {
32607    for (var i = 0; i < size; ++i) {
32608      that[i] = 0
32609    }
32610  }
32611  return that
32612}
32613
32614/**
32615 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
32616 * */
32617Buffer.allocUnsafe = function (size) {
32618  return allocUnsafe(null, size)
32619}
32620/**
32621 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
32622 */
32623Buffer.allocUnsafeSlow = function (size) {
32624  return allocUnsafe(null, size)
32625}
32626
32627function fromString (that, string, encoding) {
32628  if (typeof encoding !== 'string' || encoding === '') {
32629    encoding = 'utf8'
32630  }
32631
32632  if (!Buffer.isEncoding(encoding)) {
32633    throw new TypeError('"encoding" must be a valid string encoding')
32634  }
32635
32636  var length = byteLength(string, encoding) | 0
32637  that = createBuffer(that, length)
32638
32639  var actual = that.write(string, encoding)
32640
32641  if (actual !== length) {
32642    // Writing a hex string, for example, that contains invalid characters will
32643    // cause everything after the first invalid character to be ignored. (e.g.
32644    // 'abxxcd' will be treated as 'ab')
32645    that = that.slice(0, actual)
32646  }
32647
32648  return that
32649}
32650
32651function fromArrayLike (that, array) {
32652  var length = array.length < 0 ? 0 : checked(array.length) | 0
32653  that = createBuffer(that, length)
32654  for (var i = 0; i < length; i += 1) {
32655    that[i] = array[i] & 255
32656  }
32657  return that
32658}
32659
32660function fromArrayBuffer (that, array, byteOffset, length) {
32661  array.byteLength // this throws if `array` is not a valid ArrayBuffer
32662
32663  if (byteOffset < 0 || array.byteLength < byteOffset) {
32664    throw new RangeError('\'offset\' is out of bounds')
32665  }
32666
32667  if (array.byteLength < byteOffset + (length || 0)) {
32668    throw new RangeError('\'length\' is out of bounds')
32669  }
32670
32671  if (byteOffset === undefined && length === undefined) {
32672    array = new Uint8Array(array)
32673  } else if (length === undefined) {
32674    array = new Uint8Array(array, byteOffset)
32675  } else {
32676    array = new Uint8Array(array, byteOffset, length)
32677  }
32678
32679  if (Buffer.TYPED_ARRAY_SUPPORT) {
32680    // Return an augmented `Uint8Array` instance, for best performance
32681    that = array
32682    that.__proto__ = Buffer.prototype
32683  } else {
32684    // Fallback: Return an object instance of the Buffer class
32685    that = fromArrayLike(that, array)
32686  }
32687  return that
32688}
32689
32690function fromObject (that, obj) {
32691  if (Buffer.isBuffer(obj)) {
32692    var len = checked(obj.length) | 0
32693    that = createBuffer(that, len)
32694
32695    if (that.length === 0) {
32696      return that
32697    }
32698
32699    obj.copy(that, 0, 0, len)
32700    return that
32701  }
32702
32703  if (obj) {
32704    if ((typeof ArrayBuffer !== 'undefined' &&
32705        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
32706      if (typeof obj.length !== 'number' || isnan(obj.length)) {
32707        return createBuffer(that, 0)
32708      }
32709      return fromArrayLike(that, obj)
32710    }
32711
32712    if (obj.type === 'Buffer' && isArray(obj.data)) {
32713      return fromArrayLike(that, obj.data)
32714    }
32715  }
32716
32717  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
32718}
32719
32720function checked (length) {
32721  // Note: cannot use `length < kMaxLength()` here because that fails when
32722  // length is NaN (which is otherwise coerced to zero.)
32723  if (length >= kMaxLength()) {
32724    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
32725                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
32726  }
32727  return length | 0
32728}
32729
32730function SlowBuffer (length) {
32731  if (+length != length) { // eslint-disable-line eqeqeq
32732    length = 0
32733  }
32734  return Buffer.alloc(+length)
32735}
32736
32737Buffer.isBuffer = function isBuffer (b) {
32738  return !!(b != null && b._isBuffer)
32739}
32740
32741Buffer.compare = function compare (a, b) {
32742  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
32743    throw new TypeError('Arguments must be Buffers')
32744  }
32745
32746  if (a === b) return 0
32747
32748  var x = a.length
32749  var y = b.length
32750
32751  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
32752    if (a[i] !== b[i]) {
32753      x = a[i]
32754      y = b[i]
32755      break
32756    }
32757  }
32758
32759  if (x < y) return -1
32760  if (y < x) return 1
32761  return 0
32762}
32763
32764Buffer.isEncoding = function isEncoding (encoding) {
32765  switch (String(encoding).toLowerCase()) {
32766    case 'hex':
32767    case 'utf8':
32768    case 'utf-8':
32769    case 'ascii':
32770    case 'latin1':
32771    case 'binary':
32772    case 'base64':
32773    case 'ucs2':
32774    case 'ucs-2':
32775    case 'utf16le':
32776    case 'utf-16le':
32777      return true
32778    default:
32779      return false
32780  }
32781}
32782
32783Buffer.concat = function concat (list, length) {
32784  if (!isArray(list)) {
32785    throw new TypeError('"list" argument must be an Array of Buffers')
32786  }
32787
32788  if (list.length === 0) {
32789    return Buffer.alloc(0)
32790  }
32791
32792  var i
32793  if (length === undefined) {
32794    length = 0
32795    for (i = 0; i < list.length; ++i) {
32796      length += list[i].length
32797    }
32798  }
32799
32800  var buffer = Buffer.allocUnsafe(length)
32801  var pos = 0
32802  for (i = 0; i < list.length; ++i) {
32803    var buf = list[i]
32804    if (!Buffer.isBuffer(buf)) {
32805      throw new TypeError('"list" argument must be an Array of Buffers')
32806    }
32807    buf.copy(buffer, pos)
32808    pos += buf.length
32809  }
32810  return buffer
32811}
32812
32813function byteLength (string, encoding) {
32814  if (Buffer.isBuffer(string)) {
32815    return string.length
32816  }
32817  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
32818      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
32819    return string.byteLength
32820  }
32821  if (typeof string !== 'string') {
32822    string = '' + string
32823  }
32824
32825  var len = string.length
32826  if (len === 0) return 0
32827
32828  // Use a for loop to avoid recursion
32829  var loweredCase = false
32830  for (;;) {
32831    switch (encoding) {
32832      case 'ascii':
32833      case 'latin1':
32834      case 'binary':
32835        return len
32836      case 'utf8':
32837      case 'utf-8':
32838      case undefined:
32839        return utf8ToBytes(string).length
32840      case 'ucs2':
32841      case 'ucs-2':
32842      case 'utf16le':
32843      case 'utf-16le':
32844        return len * 2
32845      case 'hex':
32846        return len >>> 1
32847      case 'base64':
32848        return base64ToBytes(string).length
32849      default:
32850        if (loweredCase) return utf8ToBytes(string).length // assume utf8
32851        encoding = ('' + encoding).toLowerCase()
32852        loweredCase = true
32853    }
32854  }
32855}
32856Buffer.byteLength = byteLength
32857
32858function slowToString (encoding, start, end) {
32859  var loweredCase = false
32860
32861  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
32862  // property of a typed array.
32863
32864  // This behaves neither like String nor Uint8Array in that we set start/end
32865  // to their upper/lower bounds if the value passed is out of range.
32866  // undefined is handled specially as per ECMA-262 6th Edition,
32867  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
32868  if (start === undefined || start < 0) {
32869    start = 0
32870  }
32871  // Return early if start > this.length. Done here to prevent potential uint32
32872  // coercion fail below.
32873  if (start > this.length) {
32874    return ''
32875  }
32876
32877  if (end === undefined || end > this.length) {
32878    end = this.length
32879  }
32880
32881  if (end <= 0) {
32882    return ''
32883  }
32884
32885  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
32886  end >>>= 0
32887  start >>>= 0
32888
32889  if (end <= start) {
32890    return ''
32891  }
32892
32893  if (!encoding) encoding = 'utf8'
32894
32895  while (true) {
32896    switch (encoding) {
32897      case 'hex':
32898        return hexSlice(this, start, end)
32899
32900      case 'utf8':
32901      case 'utf-8':
32902        return utf8Slice(this, start, end)
32903
32904      case 'ascii':
32905        return asciiSlice(this, start, end)
32906
32907      case 'latin1':
32908      case 'binary':
32909        return latin1Slice(this, start, end)
32910
32911      case 'base64':
32912        return base64Slice(this, start, end)
32913
32914      case 'ucs2':
32915      case 'ucs-2':
32916      case 'utf16le':
32917      case 'utf-16le':
32918        return utf16leSlice(this, start, end)
32919
32920      default:
32921        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
32922        encoding = (encoding + '').toLowerCase()
32923        loweredCase = true
32924    }
32925  }
32926}
32927
32928// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
32929// Buffer instances.
32930Buffer.prototype._isBuffer = true
32931
32932function swap (b, n, m) {
32933  var i = b[n]
32934  b[n] = b[m]
32935  b[m] = i
32936}
32937
32938Buffer.prototype.swap16 = function swap16 () {
32939  var len = this.length
32940  if (len % 2 !== 0) {
32941    throw new RangeError('Buffer size must be a multiple of 16-bits')
32942  }
32943  for (var i = 0; i < len; i += 2) {
32944    swap(this, i, i + 1)
32945  }
32946  return this
32947}
32948
32949Buffer.prototype.swap32 = function swap32 () {
32950  var len = this.length
32951  if (len % 4 !== 0) {
32952    throw new RangeError('Buffer size must be a multiple of 32-bits')
32953  }
32954  for (var i = 0; i < len; i += 4) {
32955    swap(this, i, i + 3)
32956    swap(this, i + 1, i + 2)
32957  }
32958  return this
32959}
32960
32961Buffer.prototype.swap64 = function swap64 () {
32962  var len = this.length
32963  if (len % 8 !== 0) {
32964    throw new RangeError('Buffer size must be a multiple of 64-bits')
32965  }
32966  for (var i = 0; i < len; i += 8) {
32967    swap(this, i, i + 7)
32968    swap(this, i + 1, i + 6)
32969    swap(this, i + 2, i + 5)
32970    swap(this, i + 3, i + 4)
32971  }
32972  return this
32973}
32974
32975Buffer.prototype.toString = function toString () {
32976  var length = this.length | 0
32977  if (length === 0) return ''
32978  if (arguments.length === 0) return utf8Slice(this, 0, length)
32979  return slowToString.apply(this, arguments)
32980}
32981
32982Buffer.prototype.equals = function equals (b) {
32983  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
32984  if (this === b) return true
32985  return Buffer.compare(this, b) === 0
32986}
32987
32988Buffer.prototype.inspect = function inspect () {
32989  var str = ''
32990  var max = exports.INSPECT_MAX_BYTES
32991  if (this.length > 0) {
32992    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
32993    if (this.length > max) str += ' ... '
32994  }
32995  return '<Buffer ' + str + '>'
32996}
32997
32998Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
32999  if (!Buffer.isBuffer(target)) {
33000    throw new TypeError('Argument must be a Buffer')
33001  }
33002
33003  if (start === undefined) {
33004    start = 0
33005  }
33006  if (end === undefined) {
33007    end = target ? target.length : 0
33008  }
33009  if (thisStart === undefined) {
33010    thisStart = 0
33011  }
33012  if (thisEnd === undefined) {
33013    thisEnd = this.length
33014  }
33015
33016  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
33017    throw new RangeError('out of range index')
33018  }
33019
33020  if (thisStart >= thisEnd && start >= end) {
33021    return 0
33022  }
33023  if (thisStart >= thisEnd) {
33024    return -1
33025  }
33026  if (start >= end) {
33027    return 1
33028  }
33029
33030  start >>>= 0
33031  end >>>= 0
33032  thisStart >>>= 0
33033  thisEnd >>>= 0
33034
33035  if (this === target) return 0
33036
33037  var x = thisEnd - thisStart
33038  var y = end - start
33039  var len = Math.min(x, y)
33040
33041  var thisCopy = this.slice(thisStart, thisEnd)
33042  var targetCopy = target.slice(start, end)
33043
33044  for (var i = 0; i < len; ++i) {
33045    if (thisCopy[i] !== targetCopy[i]) {
33046      x = thisCopy[i]
33047      y = targetCopy[i]
33048      break
33049    }
33050  }
33051
33052  if (x < y) return -1
33053  if (y < x) return 1
33054  return 0
33055}
33056
33057// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
33058// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
33059//
33060// Arguments:
33061// - buffer - a Buffer to search
33062// - val - a string, Buffer, or number
33063// - byteOffset - an index into `buffer`; will be clamped to an int32
33064// - encoding - an optional encoding, relevant is val is a string
33065// - dir - true for indexOf, false for lastIndexOf
33066function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
33067  // Empty buffer means no match
33068  if (buffer.length === 0) return -1
33069
33070  // Normalize byteOffset
33071  if (typeof byteOffset === 'string') {
33072    encoding = byteOffset
33073    byteOffset = 0
33074  } else if (byteOffset > 0x7fffffff) {
33075    byteOffset = 0x7fffffff
33076  } else if (byteOffset < -0x80000000) {
33077    byteOffset = -0x80000000
33078  }
33079  byteOffset = +byteOffset  // Coerce to Number.
33080  if (isNaN(byteOffset)) {
33081    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
33082    byteOffset = dir ? 0 : (buffer.length - 1)
33083  }
33084
33085  // Normalize byteOffset: negative offsets start from the end of the buffer
33086  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
33087  if (byteOffset >= buffer.length) {
33088    if (dir) return -1
33089    else byteOffset = buffer.length - 1
33090  } else if (byteOffset < 0) {
33091    if (dir) byteOffset = 0
33092    else return -1
33093  }
33094
33095  // Normalize val
33096  if (typeof val === 'string') {
33097    val = Buffer.from(val, encoding)
33098  }
33099
33100  // Finally, search either indexOf (if dir is true) or lastIndexOf
33101  if (Buffer.isBuffer(val)) {
33102    // Special case: looking for empty string/buffer always fails
33103    if (val.length === 0) {
33104      return -1
33105    }
33106    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
33107  } else if (typeof val === 'number') {
33108    val = val & 0xFF // Search for a byte value [0-255]
33109    if (Buffer.TYPED_ARRAY_SUPPORT &&
33110        typeof Uint8Array.prototype.indexOf === 'function') {
33111      if (dir) {
33112        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
33113      } else {
33114        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
33115      }
33116    }
33117    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
33118  }
33119
33120  throw new TypeError('val must be string, number or Buffer')
33121}
33122
33123function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
33124  var indexSize = 1
33125  var arrLength = arr.length
33126  var valLength = val.length
33127
33128  if (encoding !== undefined) {
33129    encoding = String(encoding).toLowerCase()
33130    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
33131        encoding === 'utf16le' || encoding === 'utf-16le') {
33132      if (arr.length < 2 || val.length < 2) {
33133        return -1
33134      }
33135      indexSize = 2
33136      arrLength /= 2
33137      valLength /= 2
33138      byteOffset /= 2
33139    }
33140  }
33141
33142  function read (buf, i) {
33143    if (indexSize === 1) {
33144      return buf[i]
33145    } else {
33146      return buf.readUInt16BE(i * indexSize)
33147    }
33148  }
33149
33150  var i
33151  if (dir) {
33152    var foundIndex = -1
33153    for (i = byteOffset; i < arrLength; i++) {
33154      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
33155        if (foundIndex === -1) foundIndex = i
33156        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
33157      } else {
33158        if (foundIndex !== -1) i -= i - foundIndex
33159        foundIndex = -1
33160      }
33161    }
33162  } else {
33163    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
33164    for (i = byteOffset; i >= 0; i--) {
33165      var found = true
33166      for (var j = 0; j < valLength; j++) {
33167        if (read(arr, i + j) !== read(val, j)) {
33168          found = false
33169          break
33170        }
33171      }
33172      if (found) return i
33173    }
33174  }
33175
33176  return -1
33177}
33178
33179Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
33180  return this.indexOf(val, byteOffset, encoding) !== -1
33181}
33182
33183Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
33184  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
33185}
33186
33187Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
33188  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
33189}
33190
33191function hexWrite (buf, string, offset, length) {
33192  offset = Number(offset) || 0
33193  var remaining = buf.length - offset
33194  if (!length) {
33195    length = remaining
33196  } else {
33197    length = Number(length)
33198    if (length > remaining) {
33199      length = remaining
33200    }
33201  }
33202
33203  // must be an even number of digits
33204  var strLen = string.length
33205  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
33206
33207  if (length > strLen / 2) {
33208    length = strLen / 2
33209  }
33210  for (var i = 0; i < length; ++i) {
33211    var parsed = parseInt(string.substr(i * 2, 2), 16)
33212    if (isNaN(parsed)) return i
33213    buf[offset + i] = parsed
33214  }
33215  return i
33216}
33217
33218function utf8Write (buf, string, offset, length) {
33219  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
33220}
33221
33222function asciiWrite (buf, string, offset, length) {
33223  return blitBuffer(asciiToBytes(string), buf, offset, length)
33224}
33225
33226function latin1Write (buf, string, offset, length) {
33227  return asciiWrite(buf, string, offset, length)
33228}
33229
33230function base64Write (buf, string, offset, length) {
33231  return blitBuffer(base64ToBytes(string), buf, offset, length)
33232}
33233
33234function ucs2Write (buf, string, offset, length) {
33235  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
33236}
33237
33238Buffer.prototype.write = function write (string, offset, length, encoding) {
33239  // Buffer#write(string)
33240  if (offset === undefined) {
33241    encoding = 'utf8'
33242    length = this.length
33243    offset = 0
33244  // Buffer#write(string, encoding)
33245  } else if (length === undefined && typeof offset === 'string') {
33246    encoding = offset
33247    length = this.length
33248    offset = 0
33249  // Buffer#write(string, offset[, length][, encoding])
33250  } else if (isFinite(offset)) {
33251    offset = offset | 0
33252    if (isFinite(length)) {
33253      length = length | 0
33254      if (encoding === undefined) encoding = 'utf8'
33255    } else {
33256      encoding = length
33257      length = undefined
33258    }
33259  // legacy write(string, encoding, offset, length) - remove in v0.13
33260  } else {
33261    throw new Error(
33262      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
33263    )
33264  }
33265
33266  var remaining = this.length - offset
33267  if (length === undefined || length > remaining) length = remaining
33268
33269  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
33270    throw new RangeError('Attempt to write outside buffer bounds')
33271  }
33272
33273  if (!encoding) encoding = 'utf8'
33274
33275  var loweredCase = false
33276  for (;;) {
33277    switch (encoding) {
33278      case 'hex':
33279        return hexWrite(this, string, offset, length)
33280
33281      case 'utf8':
33282      case 'utf-8':
33283        return utf8Write(this, string, offset, length)
33284
33285      case 'ascii':
33286        return asciiWrite(this, string, offset, length)
33287
33288      case 'latin1':
33289      case 'binary':
33290        return latin1Write(this, string, offset, length)
33291
33292      case 'base64':
33293        // Warning: maxLength not taken into account in base64Write
33294        return base64Write(this, string, offset, length)
33295
33296      case 'ucs2':
33297      case 'ucs-2':
33298      case 'utf16le':
33299      case 'utf-16le':
33300        return ucs2Write(this, string, offset, length)
33301
33302      default:
33303        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
33304        encoding = ('' + encoding).toLowerCase()
33305        loweredCase = true
33306    }
33307  }
33308}
33309
33310Buffer.prototype.toJSON = function toJSON () {
33311  return {
33312    type: 'Buffer',
33313    data: Array.prototype.slice.call(this._arr || this, 0)
33314  }
33315}
33316
33317function base64Slice (buf, start, end) {
33318  if (start === 0 && end === buf.length) {
33319    return base64.fromByteArray(buf)
33320  } else {
33321    return base64.fromByteArray(buf.slice(start, end))
33322  }
33323}
33324
33325function utf8Slice (buf, start, end) {
33326  end = Math.min(buf.length, end)
33327  var res = []
33328
33329  var i = start
33330  while (i < end) {
33331    var firstByte = buf[i]
33332    var codePoint = null
33333    var bytesPerSequence = (firstByte > 0xEF) ? 4
33334      : (firstByte > 0xDF) ? 3
33335      : (firstByte > 0xBF) ? 2
33336      : 1
33337
33338    if (i + bytesPerSequence <= end) {
33339      var secondByte, thirdByte, fourthByte, tempCodePoint
33340
33341      switch (bytesPerSequence) {
33342        case 1:
33343          if (firstByte < 0x80) {
33344            codePoint = firstByte
33345          }
33346          break
33347        case 2:
33348          secondByte = buf[i + 1]
33349          if ((secondByte & 0xC0) === 0x80) {
33350            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
33351            if (tempCodePoint > 0x7F) {
33352              codePoint = tempCodePoint
33353            }
33354          }
33355          break
33356        case 3:
33357          secondByte = buf[i + 1]
33358          thirdByte = buf[i + 2]
33359          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
33360            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
33361            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
33362              codePoint = tempCodePoint
33363            }
33364          }
33365          break
33366        case 4:
33367          secondByte = buf[i + 1]
33368          thirdByte = buf[i + 2]
33369          fourthByte = buf[i + 3]
33370          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
33371            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
33372            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
33373              codePoint = tempCodePoint
33374            }
33375          }
33376      }
33377    }
33378
33379    if (codePoint === null) {
33380      // we did not generate a valid codePoint so insert a
33381      // replacement char (U+FFFD) and advance only 1 byte
33382      codePoint = 0xFFFD
33383      bytesPerSequence = 1
33384    } else if (codePoint > 0xFFFF) {
33385      // encode to utf16 (surrogate pair dance)
33386      codePoint -= 0x10000
33387      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
33388      codePoint = 0xDC00 | codePoint & 0x3FF
33389    }
33390
33391    res.push(codePoint)
33392    i += bytesPerSequence
33393  }
33394
33395  return decodeCodePointsArray(res)
33396}
33397
33398// Based on http://stackoverflow.com/a/22747272/680742, the browser with
33399// the lowest limit is Chrome, with 0x10000 args.
33400// We go 1 magnitude less, for safety
33401var MAX_ARGUMENTS_LENGTH = 0x1000
33402
33403function decodeCodePointsArray (codePoints) {
33404  var len = codePoints.length
33405  if (len <= MAX_ARGUMENTS_LENGTH) {
33406    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
33407  }
33408
33409  // Decode in chunks to avoid "call stack size exceeded".
33410  var res = ''
33411  var i = 0
33412  while (i < len) {
33413    res += String.fromCharCode.apply(
33414      String,
33415      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
33416    )
33417  }
33418  return res
33419}
33420
33421function asciiSlice (buf, start, end) {
33422  var ret = ''
33423  end = Math.min(buf.length, end)
33424
33425  for (var i = start; i < end; ++i) {
33426    ret += String.fromCharCode(buf[i] & 0x7F)
33427  }
33428  return ret
33429}
33430
33431function latin1Slice (buf, start, end) {
33432  var ret = ''
33433  end = Math.min(buf.length, end)
33434
33435  for (var i = start; i < end; ++i) {
33436    ret += String.fromCharCode(buf[i])
33437  }
33438  return ret
33439}
33440
33441function hexSlice (buf, start, end) {
33442  var len = buf.length
33443
33444  if (!start || start < 0) start = 0
33445  if (!end || end < 0 || end > len) end = len
33446
33447  var out = ''
33448  for (var i = start; i < end; ++i) {
33449    out += toHex(buf[i])
33450  }
33451  return out
33452}
33453
33454function utf16leSlice (buf, start, end) {
33455  var bytes = buf.slice(start, end)
33456  var res = ''
33457  for (var i = 0; i < bytes.length; i += 2) {
33458    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
33459  }
33460  return res
33461}
33462
33463Buffer.prototype.slice = function slice (start, end) {
33464  var len = this.length
33465  start = ~~start
33466  end = end === undefined ? len : ~~end
33467
33468  if (start < 0) {
33469    start += len
33470    if (start < 0) start = 0
33471  } else if (start > len) {
33472    start = len
33473  }
33474
33475  if (end < 0) {
33476    end += len
33477    if (end < 0) end = 0
33478  } else if (end > len) {
33479    end = len
33480  }
33481
33482  if (end < start) end = start
33483
33484  var newBuf
33485  if (Buffer.TYPED_ARRAY_SUPPORT) {
33486    newBuf = this.subarray(start, end)
33487    newBuf.__proto__ = Buffer.prototype
33488  } else {
33489    var sliceLen = end - start
33490    newBuf = new Buffer(sliceLen, undefined)
33491    for (var i = 0; i < sliceLen; ++i) {
33492      newBuf[i] = this[i + start]
33493    }
33494  }
33495
33496  return newBuf
33497}
33498
33499/*
33500 * Need to make sure that buffer isn't trying to write out of bounds.
33501 */
33502function checkOffset (offset, ext, length) {
33503  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
33504  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
33505}
33506
33507Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
33508  offset = offset | 0
33509  byteLength = byteLength | 0
33510  if (!noAssert) checkOffset(offset, byteLength, this.length)
33511
33512  var val = this[offset]
33513  var mul = 1
33514  var i = 0
33515  while (++i < byteLength && (mul *= 0x100)) {
33516    val += this[offset + i] * mul
33517  }
33518
33519  return val
33520}
33521
33522Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
33523  offset = offset | 0
33524  byteLength = byteLength | 0
33525  if (!noAssert) {
33526    checkOffset(offset, byteLength, this.length)
33527  }
33528
33529  var val = this[offset + --byteLength]
33530  var mul = 1
33531  while (byteLength > 0 && (mul *= 0x100)) {
33532    val += this[offset + --byteLength] * mul
33533  }
33534
33535  return val
33536}
33537
33538Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
33539  if (!noAssert) checkOffset(offset, 1, this.length)
33540  return this[offset]
33541}
33542
33543Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
33544  if (!noAssert) checkOffset(offset, 2, this.length)
33545  return this[offset] | (this[offset + 1] << 8)
33546}
33547
33548Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
33549  if (!noAssert) checkOffset(offset, 2, this.length)
33550  return (this[offset] << 8) | this[offset + 1]
33551}
33552
33553Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
33554  if (!noAssert) checkOffset(offset, 4, this.length)
33555
33556  return ((this[offset]) |
33557      (this[offset + 1] << 8) |
33558      (this[offset + 2] << 16)) +
33559      (this[offset + 3] * 0x1000000)
33560}
33561
33562Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
33563  if (!noAssert) checkOffset(offset, 4, this.length)
33564
33565  return (this[offset] * 0x1000000) +
33566    ((this[offset + 1] << 16) |
33567    (this[offset + 2] << 8) |
33568    this[offset + 3])
33569}
33570
33571Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
33572  offset = offset | 0
33573  byteLength = byteLength | 0
33574  if (!noAssert) checkOffset(offset, byteLength, this.length)
33575
33576  var val = this[offset]
33577  var mul = 1
33578  var i = 0
33579  while (++i < byteLength && (mul *= 0x100)) {
33580    val += this[offset + i] * mul
33581  }
33582  mul *= 0x80
33583
33584  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
33585
33586  return val
33587}
33588
33589Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
33590  offset = offset | 0
33591  byteLength = byteLength | 0
33592  if (!noAssert) checkOffset(offset, byteLength, this.length)
33593
33594  var i = byteLength
33595  var mul = 1
33596  var val = this[offset + --i]
33597  while (i > 0 && (mul *= 0x100)) {
33598    val += this[offset + --i] * mul
33599  }
33600  mul *= 0x80
33601
33602  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
33603
33604  return val
33605}
33606
33607Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
33608  if (!noAssert) checkOffset(offset, 1, this.length)
33609  if (!(this[offset] & 0x80)) return (this[offset])
33610  return ((0xff - this[offset] + 1) * -1)
33611}
33612
33613Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
33614  if (!noAssert) checkOffset(offset, 2, this.length)
33615  var val = this[offset] | (this[offset + 1] << 8)
33616  return (val & 0x8000) ? val | 0xFFFF0000 : val
33617}
33618
33619Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
33620  if (!noAssert) checkOffset(offset, 2, this.length)
33621  var val = this[offset + 1] | (this[offset] << 8)
33622  return (val & 0x8000) ? val | 0xFFFF0000 : val
33623}
33624
33625Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
33626  if (!noAssert) checkOffset(offset, 4, this.length)
33627
33628  return (this[offset]) |
33629    (this[offset + 1] << 8) |
33630    (this[offset + 2] << 16) |
33631    (this[offset + 3] << 24)
33632}
33633
33634Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
33635  if (!noAssert) checkOffset(offset, 4, this.length)
33636
33637  return (this[offset] << 24) |
33638    (this[offset + 1] << 16) |
33639    (this[offset + 2] << 8) |
33640    (this[offset + 3])
33641}
33642
33643Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
33644  if (!noAssert) checkOffset(offset, 4, this.length)
33645  return ieee754.read(this, offset, true, 23, 4)
33646}
33647
33648Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
33649  if (!noAssert) checkOffset(offset, 4, this.length)
33650  return ieee754.read(this, offset, false, 23, 4)
33651}
33652
33653Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
33654  if (!noAssert) checkOffset(offset, 8, this.length)
33655  return ieee754.read(this, offset, true, 52, 8)
33656}
33657
33658Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
33659  if (!noAssert) checkOffset(offset, 8, this.length)
33660  return ieee754.read(this, offset, false, 52, 8)
33661}
33662
33663function checkInt (buf, value, offset, ext, max, min) {
33664  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
33665  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
33666  if (offset + ext > buf.length) throw new RangeError('Index out of range')
33667}
33668
33669Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
33670  value = +value
33671  offset = offset | 0
33672  byteLength = byteLength | 0
33673  if (!noAssert) {
33674    var maxBytes = Math.pow(2, 8 * byteLength) - 1
33675    checkInt(this, value, offset, byteLength, maxBytes, 0)
33676  }
33677
33678  var mul = 1
33679  var i = 0
33680  this[offset] = value & 0xFF
33681  while (++i < byteLength && (mul *= 0x100)) {
33682    this[offset + i] = (value / mul) & 0xFF
33683  }
33684
33685  return offset + byteLength
33686}
33687
33688Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
33689  value = +value
33690  offset = offset | 0
33691  byteLength = byteLength | 0
33692  if (!noAssert) {
33693    var maxBytes = Math.pow(2, 8 * byteLength) - 1
33694    checkInt(this, value, offset, byteLength, maxBytes, 0)
33695  }
33696
33697  var i = byteLength - 1
33698  var mul = 1
33699  this[offset + i] = value & 0xFF
33700  while (--i >= 0 && (mul *= 0x100)) {
33701    this[offset + i] = (value / mul) & 0xFF
33702  }
33703
33704  return offset + byteLength
33705}
33706
33707Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
33708  value = +value
33709  offset = offset | 0
33710  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
33711  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
33712  this[offset] = (value & 0xff)
33713  return offset + 1
33714}
33715
33716function objectWriteUInt16 (buf, value, offset, littleEndian) {
33717  if (value < 0) value = 0xffff + value + 1
33718  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
33719    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
33720      (littleEndian ? i : 1 - i) * 8
33721  }
33722}
33723
33724Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
33725  value = +value
33726  offset = offset | 0
33727  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
33728  if (Buffer.TYPED_ARRAY_SUPPORT) {
33729    this[offset] = (value & 0xff)
33730    this[offset + 1] = (value >>> 8)
33731  } else {
33732    objectWriteUInt16(this, value, offset, true)
33733  }
33734  return offset + 2
33735}
33736
33737Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
33738  value = +value
33739  offset = offset | 0
33740  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
33741  if (Buffer.TYPED_ARRAY_SUPPORT) {
33742    this[offset] = (value >>> 8)
33743    this[offset + 1] = (value & 0xff)
33744  } else {
33745    objectWriteUInt16(this, value, offset, false)
33746  }
33747  return offset + 2
33748}
33749
33750function objectWriteUInt32 (buf, value, offset, littleEndian) {
33751  if (value < 0) value = 0xffffffff + value + 1
33752  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
33753    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
33754  }
33755}
33756
33757Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
33758  value = +value
33759  offset = offset | 0
33760  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
33761  if (Buffer.TYPED_ARRAY_SUPPORT) {
33762    this[offset + 3] = (value >>> 24)
33763    this[offset + 2] = (value >>> 16)
33764    this[offset + 1] = (value >>> 8)
33765    this[offset] = (value & 0xff)
33766  } else {
33767    objectWriteUInt32(this, value, offset, true)
33768  }
33769  return offset + 4
33770}
33771
33772Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
33773  value = +value
33774  offset = offset | 0
33775  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
33776  if (Buffer.TYPED_ARRAY_SUPPORT) {
33777    this[offset] = (value >>> 24)
33778    this[offset + 1] = (value >>> 16)
33779    this[offset + 2] = (value >>> 8)
33780    this[offset + 3] = (value & 0xff)
33781  } else {
33782    objectWriteUInt32(this, value, offset, false)
33783  }
33784  return offset + 4
33785}
33786
33787Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
33788  value = +value
33789  offset = offset | 0
33790  if (!noAssert) {
33791    var limit = Math.pow(2, 8 * byteLength - 1)
33792
33793    checkInt(this, value, offset, byteLength, limit - 1, -limit)
33794  }
33795
33796  var i = 0
33797  var mul = 1
33798  var sub = 0
33799  this[offset] = value & 0xFF
33800  while (++i < byteLength && (mul *= 0x100)) {
33801    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
33802      sub = 1
33803    }
33804    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
33805  }
33806
33807  return offset + byteLength
33808}
33809
33810Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
33811  value = +value
33812  offset = offset | 0
33813  if (!noAssert) {
33814    var limit = Math.pow(2, 8 * byteLength - 1)
33815
33816    checkInt(this, value, offset, byteLength, limit - 1, -limit)
33817  }
33818
33819  var i = byteLength - 1
33820  var mul = 1
33821  var sub = 0
33822  this[offset + i] = value & 0xFF
33823  while (--i >= 0 && (mul *= 0x100)) {
33824    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
33825      sub = 1
33826    }
33827    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
33828  }
33829
33830  return offset + byteLength
33831}
33832
33833Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
33834  value = +value
33835  offset = offset | 0
33836  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
33837  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
33838  if (value < 0) value = 0xff + value + 1
33839  this[offset] = (value & 0xff)
33840  return offset + 1
33841}
33842
33843Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
33844  value = +value
33845  offset = offset | 0
33846  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
33847  if (Buffer.TYPED_ARRAY_SUPPORT) {
33848    this[offset] = (value & 0xff)
33849    this[offset + 1] = (value >>> 8)
33850  } else {
33851    objectWriteUInt16(this, value, offset, true)
33852  }
33853  return offset + 2
33854}
33855
33856Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
33857  value = +value
33858  offset = offset | 0
33859  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
33860  if (Buffer.TYPED_ARRAY_SUPPORT) {
33861    this[offset] = (value >>> 8)
33862    this[offset + 1] = (value & 0xff)
33863  } else {
33864    objectWriteUInt16(this, value, offset, false)
33865  }
33866  return offset + 2
33867}
33868
33869Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
33870  value = +value
33871  offset = offset | 0
33872  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
33873  if (Buffer.TYPED_ARRAY_SUPPORT) {
33874    this[offset] = (value & 0xff)
33875    this[offset + 1] = (value >>> 8)
33876    this[offset + 2] = (value >>> 16)
33877    this[offset + 3] = (value >>> 24)
33878  } else {
33879    objectWriteUInt32(this, value, offset, true)
33880  }
33881  return offset + 4
33882}
33883
33884Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
33885  value = +value
33886  offset = offset | 0
33887  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
33888  if (value < 0) value = 0xffffffff + value + 1
33889  if (Buffer.TYPED_ARRAY_SUPPORT) {
33890    this[offset] = (value >>> 24)
33891    this[offset + 1] = (value >>> 16)
33892    this[offset + 2] = (value >>> 8)
33893    this[offset + 3] = (value & 0xff)
33894  } else {
33895    objectWriteUInt32(this, value, offset, false)
33896  }
33897  return offset + 4
33898}
33899
33900function checkIEEE754 (buf, value, offset, ext, max, min) {
33901  if (offset + ext > buf.length) throw new RangeError('Index out of range')
33902  if (offset < 0) throw new RangeError('Index out of range')
33903}
33904
33905function writeFloat (buf, value, offset, littleEndian, noAssert) {
33906  if (!noAssert) {
33907    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
33908  }
33909  ieee754.write(buf, value, offset, littleEndian, 23, 4)
33910  return offset + 4
33911}
33912
33913Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
33914  return writeFloat(this, value, offset, true, noAssert)
33915}
33916
33917Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
33918  return writeFloat(this, value, offset, false, noAssert)
33919}
33920
33921function writeDouble (buf, value, offset, littleEndian, noAssert) {
33922  if (!noAssert) {
33923    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
33924  }
33925  ieee754.write(buf, value, offset, littleEndian, 52, 8)
33926  return offset + 8
33927}
33928
33929Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
33930  return writeDouble(this, value, offset, true, noAssert)
33931}
33932
33933Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
33934  return writeDouble(this, value, offset, false, noAssert)
33935}
33936
33937// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
33938Buffer.prototype.copy = function copy (target, targetStart, start, end) {
33939  if (!start) start = 0
33940  if (!end && end !== 0) end = this.length
33941  if (targetStart >= target.length) targetStart = target.length
33942  if (!targetStart) targetStart = 0
33943  if (end > 0 && end < start) end = start
33944
33945  // Copy 0 bytes; we're done
33946  if (end === start) return 0
33947  if (target.length === 0 || this.length === 0) return 0
33948
33949  // Fatal error conditions
33950  if (targetStart < 0) {
33951    throw new RangeError('targetStart out of bounds')
33952  }
33953  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
33954  if (end < 0) throw new RangeError('sourceEnd out of bounds')
33955
33956  // Are we oob?
33957  if (end > this.length) end = this.length
33958  if (target.length - targetStart < end - start) {
33959    end = target.length - targetStart + start
33960  }
33961
33962  var len = end - start
33963  var i
33964
33965  if (this === target && start < targetStart && targetStart < end) {
33966    // descending copy from end
33967    for (i = len - 1; i >= 0; --i) {
33968      target[i + targetStart] = this[i + start]
33969    }
33970  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
33971    // ascending copy from start
33972    for (i = 0; i < len; ++i) {
33973      target[i + targetStart] = this[i + start]
33974    }
33975  } else {
33976    Uint8Array.prototype.set.call(
33977      target,
33978      this.subarray(start, start + len),
33979      targetStart
33980    )
33981  }
33982
33983  return len
33984}
33985
33986// Usage:
33987//    buffer.fill(number[, offset[, end]])
33988//    buffer.fill(buffer[, offset[, end]])
33989//    buffer.fill(string[, offset[, end]][, encoding])
33990Buffer.prototype.fill = function fill (val, start, end, encoding) {
33991  // Handle string cases:
33992  if (typeof val === 'string') {
33993    if (typeof start === 'string') {
33994      encoding = start
33995      start = 0
33996      end = this.length
33997    } else if (typeof end === 'string') {
33998      encoding = end
33999      end = this.length
34000    }
34001    if (val.length === 1) {
34002      var code = val.charCodeAt(0)
34003      if (code < 256) {
34004        val = code
34005      }
34006    }
34007    if (encoding !== undefined && typeof encoding !== 'string') {
34008      throw new TypeError('encoding must be a string')
34009    }
34010    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
34011      throw new TypeError('Unknown encoding: ' + encoding)
34012    }
34013  } else if (typeof val === 'number') {
34014    val = val & 255
34015  }
34016
34017  // Invalid ranges are not set to a default, so can range check early.
34018  if (start < 0 || this.length < start || this.length < end) {
34019    throw new RangeError('Out of range index')
34020  }
34021
34022  if (end <= start) {
34023    return this
34024  }
34025
34026  start = start >>> 0
34027  end = end === undefined ? this.length : end >>> 0
34028
34029  if (!val) val = 0
34030
34031  var i
34032  if (typeof val === 'number') {
34033    for (i = start; i < end; ++i) {
34034      this[i] = val
34035    }
34036  } else {
34037    var bytes = Buffer.isBuffer(val)
34038      ? val
34039      : utf8ToBytes(new Buffer(val, encoding).toString())
34040    var len = bytes.length
34041    for (i = 0; i < end - start; ++i) {
34042      this[i + start] = bytes[i % len]
34043    }
34044  }
34045
34046  return this
34047}
34048
34049// HELPER FUNCTIONS
34050// ================
34051
34052var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
34053
34054function base64clean (str) {
34055  // Node strips out invalid characters like \n and \t from the string, base64-js does not
34056  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
34057  // Node converts strings with length < 2 to ''
34058  if (str.length < 2) return ''
34059  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
34060  while (str.length % 4 !== 0) {
34061    str = str + '='
34062  }
34063  return str
34064}
34065
34066function stringtrim (str) {
34067  if (str.trim) return str.trim()
34068  return str.replace(/^\s+|\s+$/g, '')
34069}
34070
34071function toHex (n) {
34072  if (n < 16) return '0' + n.toString(16)
34073  return n.toString(16)
34074}
34075
34076function utf8ToBytes (string, units) {
34077  units = units || Infinity
34078  var codePoint
34079  var length = string.length
34080  var leadSurrogate = null
34081  var bytes = []
34082
34083  for (var i = 0; i < length; ++i) {
34084    codePoint = string.charCodeAt(i)
34085
34086    // is surrogate component
34087    if (codePoint > 0xD7FF && codePoint < 0xE000) {
34088      // last char was a lead
34089      if (!leadSurrogate) {
34090        // no lead yet
34091        if (codePoint > 0xDBFF) {
34092          // unexpected trail
34093          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
34094          continue
34095        } else if (i + 1 === length) {
34096          // unpaired lead
34097          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
34098          continue
34099        }
34100
34101        // valid lead
34102        leadSurrogate = codePoint
34103
34104        continue
34105      }
34106
34107      // 2 leads in a row
34108      if (codePoint < 0xDC00) {
34109        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
34110        leadSurrogate = codePoint
34111        continue
34112      }
34113
34114      // valid surrogate pair
34115      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
34116    } else if (leadSurrogate) {
34117      // valid bmp char, but last char was a lead
34118      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
34119    }
34120
34121    leadSurrogate = null
34122
34123    // encode utf8
34124    if (codePoint < 0x80) {
34125      if ((units -= 1) < 0) break
34126      bytes.push(codePoint)
34127    } else if (codePoint < 0x800) {
34128      if ((units -= 2) < 0) break
34129      bytes.push(
34130        codePoint >> 0x6 | 0xC0,
34131        codePoint & 0x3F | 0x80
34132      )
34133    } else if (codePoint < 0x10000) {
34134      if ((units -= 3) < 0) break
34135      bytes.push(
34136        codePoint >> 0xC | 0xE0,
34137        codePoint >> 0x6 & 0x3F | 0x80,
34138        codePoint & 0x3F | 0x80
34139      )
34140    } else if (codePoint < 0x110000) {
34141      if ((units -= 4) < 0) break
34142      bytes.push(
34143        codePoint >> 0x12 | 0xF0,
34144        codePoint >> 0xC & 0x3F | 0x80,
34145        codePoint >> 0x6 & 0x3F | 0x80,
34146        codePoint & 0x3F | 0x80
34147      )
34148    } else {
34149      throw new Error('Invalid code point')
34150    }
34151  }
34152
34153  return bytes
34154}
34155
34156function asciiToBytes (str) {
34157  var byteArray = []
34158  for (var i = 0; i < str.length; ++i) {
34159    // Node's code seems to be doing this and not & 0x7F..
34160    byteArray.push(str.charCodeAt(i) & 0xFF)
34161  }
34162  return byteArray
34163}
34164
34165function utf16leToBytes (str, units) {
34166  var c, hi, lo
34167  var byteArray = []
34168  for (var i = 0; i < str.length; ++i) {
34169    if ((units -= 2) < 0) break
34170
34171    c = str.charCodeAt(i)
34172    hi = c >> 8
34173    lo = c % 256
34174    byteArray.push(lo)
34175    byteArray.push(hi)
34176  }
34177
34178  return byteArray
34179}
34180
34181function base64ToBytes (str) {
34182  return base64.toByteArray(base64clean(str))
34183}
34184
34185function blitBuffer (src, dst, offset, length) {
34186  for (var i = 0; i < length; ++i) {
34187    if ((i + offset >= dst.length) || (i >= src.length)) break
34188    dst[i + offset] = src[i]
34189  }
34190  return i
34191}
34192
34193function isnan (val) {
34194  return val !== val // eslint-disable-line no-self-compare
34195}
34196
34197/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(
vendor: 4,037 bytes, lines 34197-34357
341972)))
34198
34199/***/ }),
34200/* 18 */
34201/***/ (function(module, exports, __webpack_require__) {
34202
34203"use strict";
34204
34205
34206exports.byteLength = byteLength
34207exports.toByteArray = toByteArray
34208exports.fromByteArray = fromByteArray
34209
34210var lookup = []
34211var revLookup = []
34212var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
34213
34214var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
34215for (var i = 0, len = code.length; i < len; ++i) {
34216  lookup[i] = code[i]
34217  revLookup[code.charCodeAt(i)] = i
34218}
34219
34220// Support decoding URL-safe base64 strings, as Node.js does.
34221// See: https://en.wikipedia.org/wiki/Base64#URL_applications
34222revLookup['-'.charCodeAt(0)] = 62
34223revLookup['_'.charCodeAt(0)] = 63
34224
34225function getLens (b64) {
34226  var len = b64.length
34227
34228  if (len % 4 > 0) {
34229    throw new Error('Invalid string. Length must be a multiple of 4')
34230  }
34231
34232  // Trim off extra bytes after placeholder bytes are found
34233  // See: https://github.com/beatgammit/base64-js/issues/42
34234  var validLen = b64.indexOf('=')
34235  if (validLen === -1) validLen = len
34236
34237  var placeHoldersLen = validLen === len
34238    ? 0
34239    : 4 - (validLen % 4)
34240
34241  return [validLen, placeHoldersLen]
34242}
34243
34244// base64 is 4/3 + up to two characters of the original data
34245function byteLength (b64) {
34246  var lens = getLens(b64)
34247  var validLen = lens[0]
34248  var placeHoldersLen = lens[1]
34249  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
34250}
34251
34252function _byteLength (b64, validLen, placeHoldersLen) {
34253  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
34254}
34255
34256function toByteArray (b64) {
34257  var tmp
34258  var lens = getLens(b64)
34259  var validLen = lens[0]
34260  var placeHoldersLen = lens[1]
34261
34262  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
34263
34264  var curByte = 0
34265
34266  // if there are placeholders, only get up to the last complete 4 chars
34267  var len = placeHoldersLen > 0
34268    ? validLen - 4
34269    : validLen
34270
34271  var i
34272  for (i = 0; i < len; i += 4) {
34273    tmp =
34274      (revLookup[b64.charCodeAt(i)] << 18) |
34275      (revLookup[b64.charCodeAt(i + 1)] << 12) |
34276      (revLookup[b64.charCodeAt(i + 2)] << 6) |
34277      revLookup[b64.charCodeAt(i + 3)]
34278    arr[curByte++] = (tmp >> 16) & 0xFF
34279    arr[curByte++] = (tmp >> 8) & 0xFF
34280    arr[curByte++] = tmp & 0xFF
34281  }
34282
34283  if (placeHoldersLen === 2) {
34284    tmp =
34285      (revLookup[b64.charCodeAt(i)] << 2) |
34286      (revLookup[b64.charCodeAt(i + 1)] >> 4)
34287    arr[curByte++] = tmp & 0xFF
34288  }
34289
34290  if (placeHoldersLen === 1) {
34291    tmp =
34292      (revLookup[b64.charCodeAt(i)] << 10) |
34293      (revLookup[b64.charCodeAt(i + 1)] << 4) |
34294      (revLookup[b64.charCodeAt(i + 2)] >> 2)
34295    arr[curByte++] = (tmp >> 8) & 0xFF
34296    arr[curByte++] = tmp & 0xFF
34297  }
34298
34299  return arr
34300}
34301
34302function tripletToBase64 (num) {
34303  return lookup[num >> 18 & 0x3F] +
34304    lookup[num >> 12 & 0x3F] +
34305    lookup[num >> 6 & 0x3F] +
34306    lookup[num & 0x3F]
34307}
34308
34309function encodeChunk (uint8, start, end) {
34310  var tmp
34311  var output = []
34312  for (var i = start; i < end; i += 3) {
34313    tmp =
34314      ((uint8[i] << 16) & 0xFF0000) +
34315      ((uint8[i + 1] << 8) & 0xFF00) +
34316      (uint8[i + 2] & 0xFF)
34317    output.push(tripletToBase64(tmp))
34318  }
34319  return output.join('')
34320}
34321
34322function fromByteArray (uint8) {
34323  var tmp
34324  var len = uint8.length
34325  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
34326  var parts = []
34327  var maxChunkLength = 16383 // must be multiple of 3
34328
34329  // go through the array every three bytes, we'll deal with trailing stuff later
34330  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
34331    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
34332  }
34333
34334  // pad the end with zeros, but make sure to not forget the extra bytes
34335  if (extraBytes === 1) {
34336    tmp = uint8[len - 1]
34337    parts.push(
34338      lookup[tmp >> 2] +
34339      lookup[(tmp << 4) & 0x3F] +
34340      '=='
34341    )
34342  } else if (extraBytes === 2) {
34343    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
34344    parts.push(
34345      lookup[tmp >> 10] +
34346      lookup[(tmp >> 4) & 0x3F] +
34347      lookup[(tmp << 2) & 0x3F] +
34348      '='
34349    )
34350  }
34351
34352  return parts.join('')
34353}
34354
34355
34356/***/ }),
34357/* 19 */
vendor: 4,950 bytes, lines 34358-34541
34358/***/ (function(module, exports) {
34359
34360/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
34361exports.read = function (buffer, offset, isLE, mLen, nBytes) {
34362  var e, m
34363  var eLen = (nBytes * 8) - mLen - 1
34364  var eMax = (1 << eLen) - 1
34365  var eBias = eMax >> 1
34366  var nBits = -7
34367  var i = isLE ? (nBytes - 1) : 0
34368  var d = isLE ? -1 : 1
34369  var s = buffer[offset + i]
34370
34371  i += d
34372
34373  e = s & ((1 << (-nBits)) - 1)
34374  s >>= (-nBits)
34375  nBits += eLen
34376  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
34377
34378  m = e & ((1 << (-nBits)) - 1)
34379  e >>= (-nBits)
34380  nBits += mLen
34381  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
34382
34383  if (e === 0) {
34384    e = 1 - eBias
34385  } else if (e === eMax) {
34386    return m ? NaN : ((s ? -1 : 1) * Infinity)
34387  } else {
34388    m = m + Math.pow(2, mLen)
34389    e = e - eBias
34390  }
34391  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
34392}
34393
34394exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
34395  var e, m, c
34396  var eLen = (nBytes * 8) - mLen - 1
34397  var eMax = (1 << eLen) - 1
34398  var eBias = eMax >> 1
34399  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
34400  var i = isLE ? 0 : (nBytes - 1)
34401  var d = isLE ? 1 : -1
34402  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
34403
34404  value = Math.abs(value)
34405
34406  if (isNaN(value) || value === Infinity) {
34407    m = isNaN(value) ? 1 : 0
34408    e = eMax
34409  } else {
34410    e = Math.floor(Math.log(value) / Math.LN2)
34411    if (value * (c = Math.pow(2, -e)) < 1) {
34412      e--
34413      c *= 2
34414    }
34415    if (e + eBias >= 1) {
34416      value += rt / c
34417    } else {
34418      value += rt * Math.pow(2, 1 - eBias)
34419    }
34420    if (value * c >= 2) {
34421      e++
34422      c /= 2
34423    }
34424
34425    if (e + eBias >= eMax) {
34426      m = 0
34427      e = eMax
34428    } else if (e + eBias >= 1) {
34429      m = ((value * c) - 1) * Math.pow(2, mLen)
34430      e = e + eBias
34431    } else {
34432      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
34433      e = 0
34434    }
34435  }
34436
34437  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
34438
34439  e = (e << mLen) | m
34440  eLen += mLen
34441  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
34442
34443  buffer[offset + i - d] |= s * 128
34444}
34445
34446
34447/***/ }),
34448/* 20 */
34449/***/ (function(module, exports) {
34450
34451var toString = {}.toString;
34452
34453module.exports = Array.isArray || function (arr) {
34454  return toString.call(arr) == '[object Array]';
34455};
34456
34457
34458/***/ }),
34459/* 21 */
34460/***/ (function(module, exports, __webpack_require__) {
34461
34462/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) ||
34463            (typeof self !== "undefined" && self) ||
34464            window;
34465var apply = Function.prototype.apply;
34466
34467// DOM APIs, for completeness
34468
34469exports.setTimeout = function() {
34470  return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);
34471};
34472exports.setInterval = function() {
34473  return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);
34474};
34475exports.clearTimeout =
34476exports.clearInterval = function(timeout) {
34477  if (timeout) {
34478    timeout.close();
34479  }
34480};
34481
34482function Timeout(id, clearFn) {
34483  this._id = id;
34484  this._clearFn = clearFn;
34485}
34486Timeout.prototype.unref = Timeout.prototype.ref = function() {};
34487Timeout.prototype.close = function() {
34488  this._clearFn.call(scope, this._id);
34489};
34490
34491// Does not start the time, just sets up the members needed.
34492exports.enroll = function(item, msecs) {
34493  clearTimeout(item._idleTimeoutId);
34494  item._idleTimeout = msecs;
34495};
34496
34497exports.unenroll = function(item) {
34498  clearTimeout(item._idleTimeoutId);
34499  item._idleTimeout = -1;
34500};
34501
34502exports._unrefActive = exports.active = function(item) {
34503  clearTimeout(item._idleTimeoutId);
34504
34505  var msecs = item._idleTimeout;
34506  if (msecs >= 0) {
34507    item._idleTimeoutId = setTimeout(function onTimeout() {
34508      if (item._onTimeout)
34509        item._onTimeout();
34510    }, msecs);
34511  }
34512};
34513
34514// setimmediate attaches itself to the global object
34515__webpack_require__(22);
34516// On some exotic environments, it's not clear which object `setimmediate` was
34517// able to install onto.  Search each possibility in the same order as the
34518// `setimmediate` library.
34519exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
34520                       (typeof global !== "undefined" && global.setImmediate) ||
34521                       (this && this.setImmediate);
34522exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
34523                         (typeof global !== "undefined" && global.clearImmediate) ||
34524                         (this && this.clearImmediate);
34525
34526/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2)))
34527
34528/***/ }),
34529/* 22 */
34530/***/ (function(module, exports, __webpack_require__) {
34531
34532/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
34533    "use strict";
34534
34535    if (global.setImmediate) {
34536        return;
34537    }
34538
34539    var nextHandle = 1; // Spec says greater than zero
34540    var tasksByHandle = {};
34541    var currentlyRunningATask = false;
vendor: 5,701 bytes, lines 34542-34702
34542    var doc = global.document;
34543    var registerImmediate;
34544
34545    function setImmediate(callback) {
34546      // Callback can either be a function or a string
34547      if (typeof callback !== "function") {
34548        callback = new Function("" + callback);
34549      }
34550      // Copy function arguments
34551      var args = new Array(arguments.length - 1);
34552      for (var i = 0; i < args.length; i++) {
34553          args[i] = arguments[i + 1];
34554      }
34555      // Store and register the task
34556      var task = { callback: callback, args: args };
34557      tasksByHandle[nextHandle] = task;
34558      registerImmediate(nextHandle);
34559      return nextHandle++;
34560    }
34561
34562    function clearImmediate(handle) {
34563        delete tasksByHandle[handle];
34564    }
34565
34566    function run(task) {
34567        var callback = task.callback;
34568        var args = task.args;
34569        switch (args.length) {
34570        case 0:
34571            callback();
34572            break;
34573        case 1:
34574            callback(args[0]);
34575            break;
34576        case 2:
34577            callback(args[0], args[1]);
34578            break;
34579        case 3:
34580            callback(args[0], args[1], args[2]);
34581            break;
34582        default:
34583            callback.apply(undefined, args);
34584            break;
34585        }
34586    }
34587
34588    function runIfPresent(handle) {
34589        // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
34590        // So if we're currently running a task, we'll need to delay this invocation.
34591        if (currentlyRunningATask) {
34592            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
34593            // "too much recursion" error.
34594            setTimeout(runIfPresent, 0, handle);
34595        } else {
34596            var task = tasksByHandle[handle];
34597            if (task) {
34598                currentlyRunningATask = true;
34599                try {
34600                    run(task);
34601                } finally {
34602                    clearImmediate(handle);
34603                    currentlyRunningATask = false;
34604                }
34605            }
34606        }
34607    }
34608
34609    function installNextTickImplementation() {
34610        registerImmediate = function(handle) {
34611            process.nextTick(function () { runIfPresent(handle); });
34612        };
34613    }
34614
34615    function canUsePostMessage() {
34616        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
34617        // where `global.postMessage` means something completely different and can't be used for this purpose.
34618        if (global.postMessage && !global.importScripts) {
34619            var postMessageIsAsynchronous = true;
34620            var oldOnMessage = global.onmessage;
34621            global.onmessage = function() {
34622                postMessageIsAsynchronous = false;
34623            };
34624            global.postMessage("", "*");
34625            global.onmessage = oldOnMessage;
34626            return postMessageIsAsynchronous;
34627        }
34628    }
34629
34630    function installPostMessageImplementation() {
34631        // Installs an event handler on `global` for the `message` event: see
34632        // * https://developer.mozilla.org/en/DOM/window.postMessage
34633        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
34634
34635        var messagePrefix = "setImmediate$" + Math.random() + "$";
34636        var onGlobalMessage = function(event) {
34637            if (event.source === global &&
34638                typeof event.data === "string" &&
34639                event.data.indexOf(messagePrefix) === 0) {
34640                runIfPresent(+event.data.slice(messagePrefix.length));
34641            }
34642        };
34643
34644        if (global.addEventListener) {
34645            global.addEventListener("message", onGlobalMessage, false);
34646        } else {
34647            global.attachEvent("onmessage", onGlobalMessage);
34648        }
34649
34650        registerImmediate = function(handle) {
34651            global.postMessage(messagePrefix + handle, "*");
34652        };
34653    }
34654
34655    function installMessageChannelImplementation() {
34656        var channel = new MessageChannel();
34657        channel.port1.onmessage = function(event) {
34658            var handle = event.data;
34659            runIfPresent(handle);
34660        };
34661
34662        registerImmediate = function(handle) {
34663            channel.port2.postMessage(handle);
34664        };
34665    }
34666
34667    function installReadyStateChangeImplementation() {
34668        var html = doc.documentElement;
34669        registerImmediate = function(handle) {
34670            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
34671            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
34672            var script = doc.createElement("script");
34673            script.onreadystatechange = function () {
34674                runIfPresent(handle);
34675                script.onreadystatechange = null;
34676                html.removeChild(script);
34677                script = null;
34678            };
34679            html.appendChild(script);
34680        };
34681    }
34682
34683    function installSetTimeoutImplementation() {
34684        registerImmediate = function(handle) {
34685            setTimeout(runIfPresent, 0, handle);
34686        };
34687    }
34688
34689    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
34690    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
34691    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
34692
34693    // Don't get fooled by e.g. browserify environments.
34694    if ({}.toString.call(global.process) === "[object process]") {
34695        // For Node.js before 0.9
34696        installNextTickImplementation();
34697
34698    } else if (canUsePostMessage()) {
34699        // For non-IE10 modern browsers
34700        installPostMessageImplementation();
34701
34702    }
vendor: 4,139 bytes, lines 34702-34823
34702 else if (global.MessageChannel) {
34703        // For web workers, where supported
34704        installMessageChannelImplementation();
34705
34706    } else if (doc && "onreadystatechange" in doc.createElement("script")) {
34707        // For IE 6–8
34708        installReadyStateChangeImplementation();
34709
34710    } else {
34711        // For older browsers
34712        installSetTimeoutImplementation();
34713    }
34714
34715    attachTo.setImmediate = setImmediate;
34716    attachTo.clearImmediate = clearImmediate;
34717}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
34718
34719/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2), __webpack_require__(23)))
34720
34721/***/ }),
34722/* 23 */
34723/***/ (function(module, exports) {
34724
34725// shim for using process in browser
34726var process = module.exports = {};
34727
34728// cached from whatever global is present so that test runners that stub it
34729// don't break things.  But we need to wrap it in a try catch in case it is
34730// wrapped in strict mode code which doesn't define any globals.  It's inside a
34731// function because try/catches deoptimize in certain engines.
34732
34733var cachedSetTimeout;
34734var cachedClearTimeout;
34735
34736function defaultSetTimout() {
34737    throw new Error('setTimeout has not been defined');
34738}
34739function defaultClearTimeout () {
34740    throw new Error('clearTimeout has not been defined');
34741}
34742(function () {
34743    try {
34744        if (typeof setTimeout === 'function') {
34745            cachedSetTimeout = setTimeout;
34746        } else {
34747            cachedSetTimeout = defaultSetTimout;
34748        }
34749    } catch (e) {
34750        cachedSetTimeout = defaultSetTimout;
34751    }
34752    try {
34753        if (typeof clearTimeout === 'function') {
34754            cachedClearTimeout = clearTimeout;
34755        } else {
34756            cachedClearTimeout = defaultClearTimeout;
34757        }
34758    } catch (e) {
34759        cachedClearTimeout = defaultClearTimeout;
34760    }
34761} ())
34762function runTimeout(fun) {
34763    if (cachedSetTimeout === setTimeout) {
34764        //normal enviroments in sane situations
34765        return setTimeout(fun, 0);
34766    }
34767    // if setTimeout wasn't available but was latter defined
34768    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
34769        cachedSetTimeout = setTimeout;
34770        return setTimeout(fun, 0);
34771    }
34772    try {
34773        // when when somebody has screwed with setTimeout but no I.E. maddness
34774        return cachedSetTimeout(fun, 0);
34775    } catch(e){
34776        try {
34777            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
34778            return cachedSetTimeout.call(null, fun, 0);
34779        } catch(e){
34780            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
34781            return cachedSetTimeout.call(this, fun, 0);
34782        }
34783    }
34784
34785
34786}
34787function runClearTimeout(marker) {
34788    if (cachedClearTimeout === clearTimeout) {
34789        //normal enviroments in sane situations
34790        return clearTimeout(marker);
34791    }
34792    // if clearTimeout wasn't available but was latter defined
34793    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
34794        cachedClearTimeout = clearTimeout;
34795        return clearTimeout(marker);
34796    }
34797    try {
34798        // when when somebody has screwed with setTimeout but no I.E. maddness
34799        return cachedClearTimeout(marker);
34800    } catch (e){
34801        try {
34802            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
34803            return cachedClearTimeout.call(null, marker);
34804        } catch (e){
34805            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
34806            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
34807            return cachedClearTimeout.call(this, marker);
34808        }
34809    }
34810
34811
34812
34813}
34814var queue = [];
34815var draining = false;
34816var currentQueue;
34817var queueIndex = -1;
34818
34819function cleanUpNextTick() {
34820    if (!draining || !currentQueue) {
34821        return;
34822    }
34823    draining = false;
vendor: 2,164 bytes, lines 34824-34925
34824    if (currentQueue.length) {
34825        queue = currentQueue.concat(queue);
34826    } else {
34827        queueIndex = -1;
34828    }
34829    if (queue.length) {
34830        drainQueue();
34831    }
34832}
34833
34834function drainQueue() {
34835    if (draining) {
34836        return;
34837    }
34838    var timeout = runTimeout(cleanUpNextTick);
34839    draining = true;
34840
34841    var len = queue.length;
34842    while(len) {
34843        currentQueue = queue;
34844        queue = [];
34845        while (++queueIndex < len) {
34846            if (currentQueue) {
34847                currentQueue[queueIndex].run();
34848            }
34849        }
34850        queueIndex = -1;
34851        len = queue.length;
34852    }
34853    currentQueue = null;
34854    draining = false;
34855    runClearTimeout(timeout);
34856}
34857
34858process.nextTick = function (fun) {
34859    var args = new Array(arguments.length - 1);
34860    if (arguments.length > 1) {
34861        for (var i = 1; i < arguments.length; i++) {
34862            args[i - 1] = arguments[i];
34863        }
34864    }
34865    queue.push(new Item(fun, args));
34866    if (queue.length === 1 && !draining) {
34867        runTimeout(drainQueue);
34868    }
34869};
34870
34871// v8 likes predictible objects
34872function Item(fun, array) {
34873    this.fun = fun;
34874    this.array = array;
34875}
34876Item.prototype.run = function () {
34877    this.fun.apply(null, this.array);
34878};
34879process.title = 'browser';
34880process.browser = true;
34881process.env = {};
34882process.argv = [];
34883process.version = ''; // empty string to avoid regexp issues
34884process.versions = {};
34885
34886function noop() {}
34887
34888process.on = noop;
34889process.addListener = noop;
34890process.once = noop;
34891process.off = noop;
34892process.removeListener = noop;
34893process.removeAllListeners = noop;
34894process.emit = noop;
34895process.prependListener = noop;
34896process.prependOnceListener = noop;
34897
34898process.listeners = function (name) { return [] }
34899
34900process.binding = function (name) {
34901    throw new Error('process.binding is not supported');
34902};
34903
34904process.cwd = function () { return '/' };
34905process.chdir = function (dir) {
34906    throw new Error('process.chdir is not supported');
34907};
34908process.umask = function() { return 0; };
34909
34910
34911/***/ }),
34912/* 24 */,
34913/* 25 */,
34914/* 26 */,
34915/* 27 */,
34916/* 28 */,
34917/* 29 */,
34918/* 30 */,
34919/* 31 */
34920/***/ (function(module, exports) {
34921
34922// removed by extract-text-webpack-plugin
34923
34924/***/ })
34925/******/ ]);

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