PageSourceSearch

https://www.easydcim.com/client-area/templates/easydcim/assets/js/scripts.js

js easydcim.com collected 2026-10-05 19:03:22 UTC 1,563,009 bytes, 45,968 lines download raw bytes

vendor: 4,505 bytes, lines 1-180
1/*!
2 * jQuery JavaScript Library v1.12.4
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright jQuery Foundation and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2016-05-20T17:17Z
13 */
14
15(function( global, factory ) {
16
17	if ( typeof module === "object" && typeof module.exports === "object" ) {
18		// For CommonJS and CommonJS-like environments where a proper `window`
19		// is present, execute the factory and get jQuery.
20		// For environments that do not have a `window` with a `document`
21		// (such as Node.js), expose a factory as module.exports.
22		// This accentuates the need for the creation of a real `window`.
23		// e.g. var jQuery = require("jquery")(window);
24		// See ticket #14549 for more info.
25		module.exports = global.document ?
26			factory( global, true ) :
27			function( w ) {
28				if ( !w.document ) {
29					throw new Error( "jQuery requires a window with a document" );
30				}
31				return factory( w );
32			};
33	} else {
34		factory( global );
35	}
36
37// Pass this if window is not defined yet
38}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
40// Support: Firefox 18+
41// Can't be in strict mode, several libs including ASP.NET trace
42// the stack via arguments.caller.callee and Firefox dies if
43// you try to trace through "use strict" call chains. (#13335)
44//"use strict";
45	var deletedIds = [];
46
47	var document = window.document;
48
49	var slice = deletedIds.slice;
50
51	var concat = deletedIds.concat;
52
53	var push = deletedIds.push;
54
55	var indexOf = deletedIds.indexOf;
56
57	var class2type = {};
58
59	var toString = class2type.toString;
60
61	var hasOwn = class2type.hasOwnProperty;
62
63	var support = {};
64
65
66
67	var
68		version = "1.12.4",
69
70		// Define a local copy of jQuery
71		jQuery = function( selector, context ) {
72
73			// The jQuery object is actually just the init constructor 'enhanced'
74			// Need init if jQuery is called (just allow error to be thrown if not included)
75			return new jQuery.fn.init( selector, context );
76		},
77
78		// Support: Android<4.1, IE<9
79		// Make sure we trim BOM and NBSP
80		rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
81
82		// Matches dashed string for camelizing
83		rmsPrefix = /^-ms-/,
84		rdashAlpha = /-([\da-z])/gi,
85
86		// Used by jQuery.camelCase as callback to replace()
87		fcamelCase = function( all, letter ) {
88			return letter.toUpperCase();
89		};
90
91	jQuery.fn = jQuery.prototype = {
92
93		// The current version of jQuery being used
94		jquery: version,
95
96		constructor: jQuery,
97
98		// Start with an empty selector
99		selector: "",
100
101		// The default length of a jQuery object is 0
102		length: 0,
103
104		toArray: function() {
105			return slice.call( this );
106		},
107
108		// Get the Nth element in the matched element set OR
109		// Get the whole matched element set as a clean array
110		get: function( num ) {
111			return num != null ?
112
113				// Return just the one element from the set
114				( num < 0 ? this[ num + this.length ] : this[ num ] ) :
115
116				// Return all the elements in a clean array
117				slice.call( this );
118		},
119
120		// Take an array of elements and push it onto the stack
121		// (returning the new matched element set)
122		pushStack: function( elems ) {
123
124			// Build a new jQuery matched element set
125			var ret = jQuery.merge( this.constructor(), elems );
126
127			// Add the old object onto the stack (as a reference)
128			ret.prevObject = this;
129			ret.context = this.context;
130
131			// Return the newly-formed element set
132			return ret;
133		},
134
135		// Execute a callback for every element in the matched set.
136		each: function( callback ) {
137			return jQuery.each( this, callback );
138		},
139
140		map: function( callback ) {
141			return this.pushStack( jQuery.map( this, function( elem, i ) {
142				return callback.call( elem, i, elem );
143			} ) );
144		},
145
146		slice: function() {
147			return this.pushStack( slice.apply( this, arguments ) );
148		},
149
150		first: function() {
151			return this.eq( 0 );
152		},
153
154		last: function() {
155			return this.eq( -1 );
156		},
157
158		eq: function( i ) {
159			var len = this.length,
160				j = +i + ( i < 0 ? len : 0 );
161			return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
162		},
163
164		end: function() {
165			return this.prevObject || this.constructor();
166		},
167
168		// For internal use only.
169		// Behaves like an Array's method, not like a jQuery method.
170		push: push,
171		sort: deletedIds.sort,
172		splice: deletedIds.splice
173	};
174
175	jQuery.extend = jQuery.fn.extend = function() {
176		var src, copyIsArray, copy, name, options, clone,
177			target = arguments[ 0 ] || {},
178			i = 1,
179			length = arguments.length,
180			deep = false;
vendor: 9,468 bytes, lines 181-564
181
182		// Handle a deep copy situation
183		if ( typeof target === "boolean" ) {
184			deep = target;
185
186			// skip the boolean and the target
187			target = arguments[ i ] || {};
188			i++;
189		}
190
191		// Handle case when target is a string or something (possible in deep copy)
192		if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
193			target = {};
194		}
195
196		// extend jQuery itself if only one argument is passed
197		if ( i === length ) {
198			target = this;
199			i--;
200		}
201
202		for ( ; i < length; i++ ) {
203
204			// Only deal with non-null/undefined values
205			if ( ( options = arguments[ i ] ) != null ) {
206
207				// Extend the base object
208				for ( name in options ) {
209					src = target[ name ];
210					copy = options[ name ];
211
212					// Prevent never-ending loop
213					if ( target === copy ) {
214						continue;
215					}
216
217					// Recurse if we're merging plain objects or arrays
218					if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
219						( copyIsArray = jQuery.isArray( copy ) ) ) ) {
220
221						if ( copyIsArray ) {
222							copyIsArray = false;
223							clone = src && jQuery.isArray( src ) ? src : [];
224
225						} else {
226							clone = src && jQuery.isPlainObject( src ) ? src : {};
227						}
228
229						// Never move original objects, clone them
230						target[ name ] = jQuery.extend( deep, clone, copy );
231
232						// Don't bring in undefined values
233					} else if ( copy !== undefined ) {
234						target[ name ] = copy;
235					}
236				}
237			}
238		}
239
240		// Return the modified object
241		return target;
242	};
243
244	jQuery.extend( {
245
246		// Unique for each copy of jQuery on the page
247		expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
248
249		// Assume jQuery is ready without the ready module
250		isReady: true,
251
252		error: function( msg ) {
253			throw new Error( msg );
254		},
255
256		noop: function() {},
257
258		// See test/unit/core.js for details concerning isFunction.
259		// Since version 1.3, DOM methods and functions like alert
260		// aren't supported. They return false on IE (#2968).
261		isFunction: function( obj ) {
262			return jQuery.type( obj ) === "function";
263		},
264
265		isArray: Array.isArray || function( obj ) {
266			return jQuery.type( obj ) === "array";
267		},
268
269		isWindow: function( obj ) {
270			/* jshint eqeqeq: false */
271			return obj != null && obj == obj.window;
272		},
273
274		isNumeric: function( obj ) {
275
276			// parseFloat NaNs numeric-cast false positives (null|true|false|"")
277			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
278			// subtraction forces infinities to NaN
279			// adding 1 corrects loss of precision from parseFloat (#15100)
280			var realStringObj = obj && obj.toString();
281			return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
282		},
283
284		isEmptyObject: function( obj ) {
285			var name;
286			for ( name in obj ) {
287				return false;
288			}
289			return true;
290		},
291
292		isPlainObject: function( obj ) {
293			var key;
294
295			// Must be an Object.
296			// Because of IE, we also have to check the presence of the constructor property.
297			// Make sure that DOM nodes and window objects don't pass through, as well
298			if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
299				return false;
300			}
301
302			try {
303
304				// Not own constructor property must be Object
305				if ( obj.constructor &&
306					!hasOwn.call( obj, "constructor" ) &&
307					!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
308					return false;
309				}
310			} catch ( e ) {
311
312				// IE8,9 Will throw exceptions on certain host objects #9897
313				return false;
314			}
315
316			// Support: IE<9
317			// Handle iteration over inherited properties before own properties.
318			if ( !support.ownFirst ) {
319				for ( key in obj ) {
320					return hasOwn.call( obj, key );
321				}
322			}
323
324			// Own properties are enumerated firstly, so to speed up,
325			// if last one is own, then all properties are own.
326			for ( key in obj ) {}
327
328			return key === undefined || hasOwn.call( obj, key );
329		},
330
331		type: function( obj ) {
332			if ( obj == null ) {
333				return obj + "";
334			}
335			return typeof obj === "object" || typeof obj === "function" ?
336				class2type[ toString.call( obj ) ] || "object" :
337				typeof obj;
338		},
339
340		// Workarounds based on findings by Jim Driscoll
341		// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
342		globalEval: function( data ) {
343			if ( data && jQuery.trim( data ) ) {
344
345				// We use execScript on Internet Explorer
346				// We use an anonymous function so that context is window
347				// rather than jQuery in Firefox
348				( window.execScript || function( data ) {
349					window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
350				} )( data );
351			}
352		},
353
354		// Convert dashed to camelCase; used by the css and data modules
355		// Microsoft forgot to hump their vendor prefix (#9572)
356		camelCase: function( string ) {
357			return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
358		},
359
360		nodeName: function( elem, name ) {
361			return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
362		},
363
364		each: function( obj, callback ) {
365			var length, i = 0;
366
367			if ( isArrayLike( obj ) ) {
368				length = obj.length;
369				for ( ; i < length; i++ ) {
370					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371						break;
372					}
373				}
374			} else {
375				for ( i in obj ) {
376					if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
377						break;
378					}
379				}
380			}
381
382			return obj;
383		},
384
385		// Support: Android<4.1, IE<9
386		trim: function( text ) {
387			return text == null ?
388				"" :
389				( text + "" ).replace( rtrim, "" );
390		},
391
392		// results is for internal usage only
393		makeArray: function( arr, results ) {
394			var ret = results || [];
395
396			if ( arr != null ) {
397				if ( isArrayLike( Object( arr ) ) ) {
398					jQuery.merge( ret,
399						typeof arr === "string" ?
400							[ arr ] : arr
401					);
402				} else {
403					push.call( ret, arr );
404				}
405			}
406
407			return ret;
408		},
409
410		inArray: function( elem, arr, i ) {
411			var len;
412
413			if ( arr ) {
414				if ( indexOf ) {
415					return indexOf.call( arr, elem, i );
416				}
417
418				len = arr.length;
419				i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
420
421				for ( ; i < len; i++ ) {
422
423					// Skip accessing in sparse arrays
424					if ( i in arr && arr[ i ] === elem ) {
425						return i;
426					}
427				}
428			}
429
430			return -1;
431		},
432
433		merge: function( first, second ) {
434			var len = +second.length,
435				j = 0,
436				i = first.length;
437
438			while ( j < len ) {
439				first[ i++ ] = second[ j++ ];
440			}
441
442			// Support: IE<9
443			// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
444			if ( len !== len ) {
445				while ( second[ j ] !== undefined ) {
446					first[ i++ ] = second[ j++ ];
447				}
448			}
449
450			first.length = i;
451
452			return first;
453		},
454
455		grep: function( elems, callback, invert ) {
456			var callbackInverse,
457				matches = [],
458				i = 0,
459				length = elems.length,
460				callbackExpect = !invert;
461
462			// Go through the array, only saving the items
463			// that pass the validator function
464			for ( ; i < length; i++ ) {
465				callbackInverse = !callback( elems[ i ], i );
466				if ( callbackInverse !== callbackExpect ) {
467					matches.push( elems[ i ] );
468				}
469			}
470
471			return matches;
472		},
473
474		// arg is for internal usage only
475		map: function( elems, callback, arg ) {
476			var length, value,
477				i = 0,
478				ret = [];
479
480			// Go through the array, translating each of the items to their new values
481			if ( isArrayLike( elems ) ) {
482				length = elems.length;
483				for ( ; i < length; i++ ) {
484					value = callback( elems[ i ], i, arg );
485
486					if ( value != null ) {
487						ret.push( value );
488					}
489				}
490
491				// Go through every key on the object,
492			} else {
493				for ( i in elems ) {
494					value = callback( elems[ i ], i, arg );
495
496					if ( value != null ) {
497						ret.push( value );
498					}
499				}
500			}
501
502			// Flatten any nested arrays
503			return concat.apply( [], ret );
504		},
505
506		// A global GUID counter for objects
507		guid: 1,
508
509		// Bind a function to a context, optionally partially applying any
510		// arguments.
511		proxy: function( fn, context ) {
512			var args, proxy, tmp;
513
514			if ( typeof context === "string" ) {
515				tmp = fn[ context ];
516				context = fn;
517				fn = tmp;
518			}
519
520			// Quick check to determine if target is callable, in the spec
521			// this throws a TypeError, but we will just return undefined.
522			if ( !jQuery.isFunction( fn ) ) {
523				return undefined;
524			}
525
526			// Simulated bind
527			args = slice.call( arguments, 2 );
528			proxy = function() {
529				return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
530			};
531
532			// Set the guid of unique handler to the same of original handler, so it can be removed
533			proxy.guid = fn.guid = fn.guid || jQuery.guid++;
534
535			return proxy;
536		},
537
538		now: function() {
539			return +( new Date() );
540		},
541
542		// jQuery.support is not used in Core but other projects attach their
543		// properties to it so it needs to exist.
544		support: support
545	} );
546
547// JSHint would error on this code due to the Symbol not being defined in ES5.
548// Defining this global in .jshintrc would create a danger of using the global
549// unguarded in another place, it seems safer to just disable JSHint for these
550// three lines.
551	/* jshint ignore: start */
552	if ( typeof Symbol === "function" ) {
553		jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
554	}
555	/* jshint ignore: end */
556
557// Populate the class2type map
558	jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
559		function( i, name ) {
560			class2type[ "[object " + name + "]" ] = name.toLowerCase();
561		} );
562
563	function isArrayLike( obj ) {
564
vendor: 30,479 bytes, lines 565-1550
565		// Support: iOS 8.2 (not reproducible in simulator)
566		// `in` check used to prevent JIT error (gh-2145)
567		// hasOwn isn't used here due to false negatives
568		// regarding Nodelist length in IE
569		var length = !!obj && "length" in obj && obj.length,
570			type = jQuery.type( obj );
571
572		if ( type === "function" || jQuery.isWindow( obj ) ) {
573			return false;
574		}
575
576		return type === "array" || length === 0 ||
577			typeof length === "number" && length > 0 && ( length - 1 ) in obj;
578	}
579	var Sizzle =
580		/*!
581 * Sizzle CSS Selector Engine v2.2.1
582 * http://sizzlejs.com/
583 *
584 * Copyright jQuery Foundation and other contributors
585 * Released under the MIT license
586 * http://jquery.org/license
587 *
588 * Date: 2015-10-17
589 */
590		(function( window ) {
591
592			var i,
593				support,
594				Expr,
595				getText,
596				isXML,
597				tokenize,
598				compile,
599				select,
600				outermostContext,
601				sortInput,
602				hasDuplicate,
603
604				// Local document vars
605				setDocument,
606				document,
607				docElem,
608				documentIsHTML,
609				rbuggyQSA,
610				rbuggyMatches,
611				matches,
612				contains,
613
614				// Instance-specific data
615				expando = "sizzle" + 1 * new Date(),
616				preferredDoc = window.document,
617				dirruns = 0,
618				done = 0,
619				classCache = createCache(),
620				tokenCache = createCache(),
621				compilerCache = createCache(),
622				sortOrder = function( a, b ) {
623					if ( a === b ) {
624						hasDuplicate = true;
625					}
626					return 0;
627				},
628
629				// General-purpose constants
630				MAX_NEGATIVE = 1 << 31,
631
632				// Instance methods
633				hasOwn = ({}).hasOwnProperty,
634				arr = [],
635				pop = arr.pop,
636				push_native = arr.push,
637				push = arr.push,
638				slice = arr.slice,
639				// Use a stripped-down indexOf as it's faster than native
640				// http://jsperf.com/thor-indexof-vs-for/5
641				indexOf = function( list, elem ) {
642					var i = 0,
643						len = list.length;
644					for ( ; i < len; i++ ) {
645						if ( list[i] === elem ) {
646							return i;
647						}
648					}
649					return -1;
650				},
651
652				booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
653
654				// Regular expressions
655
656				// http://www.w3.org/TR/css3-selectors/#whitespace
657				whitespace = "[\\x20\\t\\r\\n\\f]",
658
659				// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
660				identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
661
662				// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
663				attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
664					// Operator (capture 2)
665					"*([*^$|!~]?=)" + whitespace +
666					// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
667					"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
668					"*\\]",
669
670				pseudos = ":(" + identifier + ")(?:\\((" +
671					// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
672					// 1. quoted (capture 3; capture 4 or capture 5)
673					"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
674					// 2. simple (capture 6)
675					"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
676					// 3. anything else (capture 2)
677					".*" +
678					")\\)|)",
679
680				// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
681				rwhitespace = new RegExp( whitespace + "+", "g" ),
682				rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
683
684				rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
685				rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
686
687				rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
688
689				rpseudo = new RegExp( pseudos ),
690				ridentifier = new RegExp( "^" + identifier + "$" ),
691
692				matchExpr = {
693					"ID": new RegExp( "^#(" + identifier + ")" ),
694					"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
695					"TAG": new RegExp( "^(" + identifier + "|[*])" ),
696					"ATTR": new RegExp( "^" + attributes ),
697					"PSEUDO": new RegExp( "^" + pseudos ),
698					"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
699						"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
700						"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
701					"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
702					// For use in libraries implementing .is()
703					// We use this for POS matching in `select`
704					"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
705						whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
706				},
707
708				rinputs = /^(?:input|select|textarea|button)$/i,
709				rheader = /^h\d$/i,
710
711				rnative = /^[^{]+\{\s*\[native \w/,
712
713				// Easily-parseable/retrievable ID or TAG or CLASS selectors
714				rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
715
716				rsibling = /[+~]/,
717				rescape = /'|\\/g,
718
719				// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
720				runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
721				funescape = function( _, escaped, escapedWhitespace ) {
722					var high = "0x" + escaped - 0x10000;
723					// NaN means non-codepoint
724					// Support: Firefox<24
725					// Workaround erroneous numeric interpretation of +"0x"
726					return high !== high || escapedWhitespace ?
727						escaped :
728						high < 0 ?
729							// BMP codepoint
730							String.fromCharCode( high + 0x10000 ) :
731							// Supplemental Plane codepoint (surrogate pair)
732							String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
733				},
734
735				// Used for iframes
736				// See setDocument()
737				// Removing the function wrapper causes a "Permission Denied"
738				// error in IE
739				unloadHandler = function() {
740					setDocument();
741				};
742
743// Optimize for push.apply( _, NodeList )
744			try {
745				push.apply(
746					(arr = slice.call( preferredDoc.childNodes )),
747					preferredDoc.childNodes
748				);
749				// Support: Android<4.0
750				// Detect silently failing push.apply
751				arr[ preferredDoc.childNodes.length ].nodeType;
752			} catch ( e ) {
753				push = { apply: arr.length ?
754
755						// Leverage slice if possible
756						function( target, els ) {
757							push_native.apply( target, slice.call(els) );
758						} :
759
760						// Support: IE<9
761						// Otherwise append directly
762						function( target, els ) {
763							var j = target.length,
764								i = 0;
765							// Can't trust NodeList.length
766							while ( (target[j++] = els[i++]) ) {}
767							target.length = j - 1;
768						}
769				};
770			}
771
772			function Sizzle( selector, context, results, seed ) {
773				var m, i, elem, nid, nidselect, match, groups, newSelector,
774					newContext = context && context.ownerDocument,
775
776					// nodeType defaults to 9, since context defaults to document
777					nodeType = context ? context.nodeType : 9;
778
779				results = results || [];
780
781				// Return early from calls with invalid selector or context
782				if ( typeof selector !== "string" || !selector ||
783					nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
784
785					return results;
786				}
787
788				// Try to shortcut find operations (as opposed to filters) in HTML documents
789				if ( !seed ) {
790
791					if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
792						setDocument( context );
793					}
794					context = context || document;
795
796					if ( documentIsHTML ) {
797
798						// If the selector is sufficiently simple, try using a "get*By*" DOM method
799						// (excepting DocumentFragment context, where the methods don't exist)
800						if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
801
802							// ID selector
803							if ( (m = match[1]) ) {
804
805								// Document context
806								if ( nodeType === 9 ) {
807									if ( (elem = context.getElementById( m )) ) {
808
809										// Support: IE, Opera, Webkit
810										// TODO: identify versions
811										// getElementById can match elements by name instead of ID
812										if ( elem.id === m ) {
813											results.push( elem );
814											return results;
815										}
816									} else {
817										return results;
818									}
819
820									// Element context
821								} else {
822
823									// Support: IE, Opera, Webkit
824									// TODO: identify versions
825									// getElementById can match elements by name instead of ID
826									if ( newContext && (elem = newContext.getElementById( m )) &&
827										contains( context, elem ) &&
828										elem.id === m ) {
829
830										results.push( elem );
831										return results;
832									}
833								}
834
835								// Type selector
836							} else if ( match[2] ) {
837								push.apply( results, context.getElementsByTagName( selector ) );
838								return results;
839
840								// Class selector
841							} else if ( (m = match[3]) && support.getElementsByClassName &&
842								context.getElementsByClassName ) {
843
844								push.apply( results, context.getElementsByClassName( m ) );
845								return results;
846							}
847						}
848
849						// Take advantage of querySelectorAll
850						if ( support.qsa &&
851							!compilerCache[ selector + " " ] &&
852							(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
853
854							if ( nodeType !== 1 ) {
855								newContext = context;
856								newSelector = selector;
857
858								// qSA looks outside Element context, which is not what we want
859								// Thanks to Andrew Dupont for this workaround technique
860								// Support: IE <=8
861								// Exclude object elements
862							} else if ( context.nodeName.toLowerCase() !== "object" ) {
863
864								// Capture the context ID, setting it first if necessary
865								if ( (nid = context.getAttribute( "id" )) ) {
866									nid = nid.replace( rescape, "\\$&" );
867								} else {
868									context.setAttribute( "id", (nid = expando) );
869								}
870
871								// Prefix every selector in the list
872								groups = tokenize( selector );
873								i = groups.length;
874								nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
875								while ( i-- ) {
876									groups[i] = nidselect + " " + toSelector( groups[i] );
877								}
878								newSelector = groups.join( "," );
879
880								// Expand context for sibling selectors
881								newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
882									context;
883							}
884
885							if ( newSelector ) {
886								try {
887									push.apply( results,
888										newContext.querySelectorAll( newSelector )
889									);
890									return results;
891								} catch ( qsaError ) {
892								} finally {
893									if ( nid === expando ) {
894										context.removeAttribute( "id" );
895									}
896								}
897							}
898						}
899					}
900				}
901
902				// All others
903				return select( selector.replace( rtrim, "$1" ), context, results, seed );
904			}
905
906			/**
907			 * Create key-value caches of limited size
908			 * @returns {function(string, object)} Returns the Object data after storing it on itself with
909			 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
910			 *	deleting the oldest entry
911			 */
912			function createCache() {
913				var keys = [];
914
915				function cache( key, value ) {
916					// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
917					if ( keys.push( key + " " ) > Expr.cacheLength ) {
918						// Only keep the most recent entries
919						delete cache[ keys.shift() ];
920					}
921					return (cache[ key + " " ] = value);
922				}
923				return cache;
924			}
925
926			/**
927			 * Mark a function for special use by Sizzle
928			 * @param {Function} fn The function to mark
929			 */
930			function markFunction( fn ) {
931				fn[ expando ] = true;
932				return fn;
933			}
934
935			/**
936			 * Support testing using an element
937			 * @param {Function} fn Passed the created div and expects a boolean result
938			 */
939			function assert( fn ) {
940				var div = document.createElement("div");
941
942				try {
943					return !!fn( div );
944				} catch (e) {
945					return false;
946				} finally {
947					// Remove from its parent by default
948					if ( div.parentNode ) {
949						div.parentNode.removeChild( div );
950					}
951					// release memory in IE
952					div = null;
953				}
954			}
955
956			/**
957			 * Adds the same handler for all of the specified attrs
958			 * @param {String} attrs Pipe-separated list of attributes
959			 * @param {Function} handler The method that will be applied
960			 */
961			function addHandle( attrs, handler ) {
962				var arr = attrs.split("|"),
963					i = arr.length;
964
965				while ( i-- ) {
966					Expr.attrHandle[ arr[i] ] = handler;
967				}
968			}
969
970			/**
971			 * Checks document order of two siblings
972			 * @param {Element} a
973			 * @param {Element} b
974			 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
975			 */
976			function siblingCheck( a, b ) {
977				var cur = b && a,
978					diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
979						( ~b.sourceIndex || MAX_NEGATIVE ) -
980						( ~a.sourceIndex || MAX_NEGATIVE );
981
982				// Use IE sourceIndex if available on both nodes
983				if ( diff ) {
984					return diff;
985				}
986
987				// Check if b follows a
988				if ( cur ) {
989					while ( (cur = cur.nextSibling) ) {
990						if ( cur === b ) {
991							return -1;
992						}
993					}
994				}
995
996				return a ? 1 : -1;
997			}
998
999			/**
1000			 * Returns a function to use in pseudos for input types
1001			 * @param {String} type
1002			 */
1003			function createInputPseudo( type ) {
1004				return function( elem ) {
1005					var name = elem.nodeName.toLowerCase();
1006					return name === "input" && elem.type === type;
1007				};
1008			}
1009
1010			/**
1011			 * Returns a function to use in pseudos for buttons
1012			 * @param {String} type
1013			 */
1014			function createButtonPseudo( type ) {
1015				return function( elem ) {
1016					var name = elem.nodeName.toLowerCase();
1017					return (name === "input" || name === "button") && elem.type === type;
1018				};
1019			}
1020
1021			/**
1022			 * Returns a function to use in pseudos for positionals
1023			 * @param {Function} fn
1024			 */
1025			function createPositionalPseudo( fn ) {
1026				return markFunction(function( argument ) {
1027					argument = +argument;
1028					return markFunction(function( seed, matches ) {
1029						var j,
1030							matchIndexes = fn( [], seed.length, argument ),
1031							i = matchIndexes.length;
1032
1033						// Match elements found at the specified indexes
1034						while ( i-- ) {
1035							if ( seed[ (j = matchIndexes[i]) ] ) {
1036								seed[j] = !(matches[j] = seed[j]);
1037							}
1038						}
1039					});
1040				});
1041			}
1042
1043			/**
1044			 * Checks a node for validity as a Sizzle context
1045			 * @param {Element|Object=} context
1046			 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1047			 */
1048			function testContext( context ) {
1049				return context && typeof context.getElementsByTagName !== "undefined" && context;
1050			}
1051
1052// Expose support vars for convenience
1053			support = Sizzle.support = {};
1054
1055			/**
1056			 * Detects XML nodes
1057			 * @param {Element|Object} elem An element or a document
1058			 * @returns {Boolean} True iff elem is a non-HTML XML node
1059			 */
1060			isXML = Sizzle.isXML = function( elem ) {
1061				// documentElement is verified for cases where it doesn't yet exist
1062				// (such as loading iframes in IE - #4833)
1063				var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1064				return documentElement ? documentElement.nodeName !== "HTML" : false;
1065			};
1066
1067			/**
1068			 * Sets document-related variables once based on the current document
1069			 * @param {Element|Object} [doc] An element or document object to use to set the document
1070			 * @returns {Object} Returns the current document
1071			 */
1072			setDocument = Sizzle.setDocument = function( node ) {
1073				var hasCompare, parent,
1074					doc = node ? node.ownerDocument || node : preferredDoc;
1075
1076				// Return early if doc is invalid or already selected
1077				if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1078					return document;
1079				}
1080
1081				// Update global variables
1082				document = doc;
1083				docElem = document.documentElement;
1084				documentIsHTML = !isXML( document );
1085
1086				// Support: IE 9-11, Edge
1087				// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1088				if ( (parent = document.defaultView) && parent.top !== parent ) {
1089					// Support: IE 11
1090					if ( parent.addEventListener ) {
1091						parent.addEventListener( "unload", unloadHandler, false );
1092
1093						// Support: IE 9 - 10 only
1094					} else if ( parent.attachEvent ) {
1095						parent.attachEvent( "onunload", unloadHandler );
1096					}
1097				}
1098
1099				/* Attributes
1100	---------------------------------------------------------------------- */
1101
1102				// Support: IE<8
1103				// Verify that getAttribute really returns attributes and not properties
1104				// (excepting IE8 booleans)
1105				support.attributes = assert(function( div ) {
1106					div.className = "i";
1107					return !div.getAttribute("className");
1108				});
1109
1110				/* getElement(s)By*
1111	---------------------------------------------------------------------- */
1112
1113				// Check if getElementsByTagName("*") returns only elements
1114				support.getElementsByTagName = assert(function( div ) {
1115					div.appendChild( document.createComment("") );
1116					return !div.getElementsByTagName("*").length;
1117				});
1118
1119				// Support: IE<9
1120				support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1121
1122				// Support: IE<10
1123				// Check if getElementById returns elements by name
1124				// The broken getElementById methods don't pick up programatically-set names,
1125				// so use a roundabout getElementsByName test
1126				support.getById = assert(function( div ) {
1127					docElem.appendChild( div ).id = expando;
1128					return !document.getElementsByName || !document.getElementsByName( expando ).length;
1129				});
1130
1131				// ID find and filter
1132				if ( support.getById ) {
1133					Expr.find["ID"] = function( id, context ) {
1134						if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1135							var m = context.getElementById( id );
1136							return m ? [ m ] : [];
1137						}
1138					};
1139					Expr.filter["ID"] = function( id ) {
1140						var attrId = id.replace( runescape, funescape );
1141						return function( elem ) {
1142							return elem.getAttribute("id") === attrId;
1143						};
1144					};
1145				} else {
1146					// Support: IE6/7
1147					// getElementById is not reliable as a find shortcut
1148					delete Expr.find["ID"];
1149
1150					Expr.filter["ID"] =  function( id ) {
1151						var attrId = id.replace( runescape, funescape );
1152						return function( elem ) {
1153							var node = typeof elem.getAttributeNode !== "undefined" &&
1154								elem.getAttributeNode("id");
1155							return node && node.value === attrId;
1156						};
1157					};
1158				}
1159
1160				// Tag
1161				Expr.find["TAG"] = support.getElementsByTagName ?
1162					function( tag, context ) {
1163						if ( typeof context.getElementsByTagName !== "undefined" ) {
1164							return context.getElementsByTagName( tag );
1165
1166							// DocumentFragment nodes don't have gEBTN
1167						} else if ( support.qsa ) {
1168							return context.querySelectorAll( tag );
1169						}
1170					} :
1171
1172					function( tag, context ) {
1173						var elem,
1174							tmp = [],
1175							i = 0,
1176							// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1177							results = context.getElementsByTagName( tag );
1178
1179						// Filter out possible comments
1180						if ( tag === "*" ) {
1181							while ( (elem = results[i++]) ) {
1182								if ( elem.nodeType === 1 ) {
1183									tmp.push( elem );
1184								}
1185							}
1186
1187							return tmp;
1188						}
1189						return results;
1190					};
1191
1192				// Class
1193				Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1194					if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1195						return context.getElementsByClassName( className );
1196					}
1197				};
1198
1199				/* QSA/matchesSelector
1200	---------------------------------------------------------------------- */
1201
1202				// QSA and matchesSelector support
1203
1204				// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1205				rbuggyMatches = [];
1206
1207				// qSa(:focus) reports false when true (Chrome 21)
1208				// We allow this because of a bug in IE8/9 that throws an error
1209				// whenever `document.activeElement` is accessed on an iframe
1210				// So, we allow :focus to pass through QSA all the time to avoid the IE error
1211				// See http://bugs.jquery.com/ticket/13378
1212				rbuggyQSA = [];
1213
1214				if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1215					// Build QSA regex
1216					// Regex strategy adopted from Diego Perini
1217					assert(function( div ) {
1218						// Select is set to empty string on purpose
1219						// This is to test IE's treatment of not explicitly
1220						// setting a boolean content attribute,
1221						// since its presence should be enough
1222						// http://bugs.jquery.com/ticket/12359
1223						docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1224							"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1225							"<option selected=''></option></select>";
1226
1227						// Support: IE8, Opera 11-12.16
1228						// Nothing should be selected when empty strings follow ^= or $= or *=
1229						// The test attribute must be unknown in Opera but "safe" for WinRT
1230						// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1231						if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1232							rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1233						}
1234
1235						// Support: IE8
1236						// Boolean attributes and "value" are not treated correctly
1237						if ( !div.querySelectorAll("[selected]").length ) {
1238							rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1239						}
1240
1241						// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1242						if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1243							rbuggyQSA.push("~=");
1244						}
1245
1246						// Webkit/Opera - :checked should return selected option elements
1247						// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1248						// IE8 throws error here and will not see later tests
1249						if ( !div.querySelectorAll(":checked").length ) {
1250							rbuggyQSA.push(":checked");
1251						}
1252
1253						// Support: Safari 8+, iOS 8+
1254						// https://bugs.webkit.org/show_bug.cgi?id=136851
1255						// In-page `selector#id sibing-combinator selector` fails
1256						if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1257							rbuggyQSA.push(".#.+[+~]");
1258						}
1259					});
1260
1261					assert(function( div ) {
1262						// Support: Windows 8 Native Apps
1263						// The type and name attributes are restricted during .innerHTML assignment
1264						var input = document.createElement("input");
1265						input.setAttribute( "type", "hidden" );
1266						div.appendChild( input ).setAttribute( "name", "D" );
1267
1268						// Support: IE8
1269						// Enforce case-sensitivity of name attribute
1270						if ( div.querySelectorAll("[name=d]").length ) {
1271							rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1272						}
1273
1274						// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1275						// IE8 throws error here and will not see later tests
1276						if ( !div.querySelectorAll(":enabled").length ) {
1277							rbuggyQSA.push( ":enabled", ":disabled" );
1278						}
1279
1280						// Opera 10-11 does not throw on post-comma invalid pseudos
1281						div.querySelectorAll("*,:x");
1282						rbuggyQSA.push(",.*:");
1283					});
1284				}
1285
1286				if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1287					docElem.webkitMatchesSelector ||
1288					docElem.mozMatchesSelector ||
1289					docElem.oMatchesSelector ||
1290					docElem.msMatchesSelector) )) ) {
1291
1292					assert(function( div ) {
1293						// Check to see if it's possible to do matchesSelector
1294						// on a disconnected node (IE 9)
1295						support.disconnectedMatch = matches.call( div, "div" );
1296
1297						// This should fail with an exception
1298						// Gecko does not error, returns false instead
1299						matches.call( div, "[s!='']:x" );
1300						rbuggyMatches.push( "!=", pseudos );
1301					});
1302				}
1303
1304				rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1305				rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1306
1307				/* Contains
1308	---------------------------------------------------------------------- */
1309				hasCompare = rnative.test( docElem.compareDocumentPosition );
1310
1311				// Element contains another
1312				// Purposefully self-exclusive
1313				// As in, an element does not contain itself
1314				contains = hasCompare || rnative.test( docElem.contains ) ?
1315					function( a, b ) {
1316						var adown = a.nodeType === 9 ? a.documentElement : a,
1317							bup = b && b.parentNode;
1318						return a === bup || !!( bup && bup.nodeType === 1 && (
1319							adown.contains ?
1320								adown.contains( bup ) :
1321								a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1322						));
1323					} :
1324					function( a, b ) {
1325						if ( b ) {
1326							while ( (b = b.parentNode) ) {
1327								if ( b === a ) {
1328									return true;
1329								}
1330							}
1331						}
1332						return false;
1333					};
1334
1335				/* Sorting
1336	---------------------------------------------------------------------- */
1337
1338				// Document order sorting
1339				sortOrder = hasCompare ?
1340					function( a, b ) {
1341
1342						// Flag for duplicate removal
1343						if ( a === b ) {
1344							hasDuplicate = true;
1345							return 0;
1346						}
1347
1348						// Sort on method existence if only one input has compareDocumentPosition
1349						var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1350						if ( compare ) {
1351							return compare;
1352						}
1353
1354						// Calculate position if both inputs belong to the same document
1355						compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1356							a.compareDocumentPosition( b ) :
1357
1358							// Otherwise we know they are disconnected
1359							1;
1360
1361						// Disconnected nodes
1362						if ( compare & 1 ||
1363							(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1364
1365							// Choose the first element that is related to our preferred document
1366							if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1367								return -1;
1368							}
1369							if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1370								return 1;
1371							}
1372
1373							// Maintain original order
1374							return sortInput ?
1375								( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1376								0;
1377						}
1378
1379						return compare & 4 ? -1 : 1;
1380					} :
1381					function( a, b ) {
1382						// Exit early if the nodes are identical
1383						if ( a === b ) {
1384							hasDuplicate = true;
1385							return 0;
1386						}
1387
1388						var cur,
1389							i = 0,
1390							aup = a.parentNode,
1391							bup = b.parentNode,
1392							ap = [ a ],
1393							bp = [ b ];
1394
1395						// Parentless nodes are either documents or disconnected
1396						if ( !aup || !bup ) {
1397							return a === document ? -1 :
1398								b === document ? 1 :
1399									aup ? -1 :
1400										bup ? 1 :
1401											sortInput ?
1402												( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1403												0;
1404
1405							// If the nodes are siblings, we can do a quick check
1406						} else if ( aup === bup ) {
1407							return siblingCheck( a, b );
1408						}
1409
1410						// Otherwise we need full lists of their ancestors for comparison
1411						cur = a;
1412						while ( (cur = cur.parentNode) ) {
1413							ap.unshift( cur );
1414						}
1415						cur = b;
1416						while ( (cur = cur.parentNode) ) {
1417							bp.unshift( cur );
1418						}
1419
1420						// Walk down the tree looking for a discrepancy
1421						while ( ap[i] === bp[i] ) {
1422							i++;
1423						}
1424
1425						return i ?
1426							// Do a sibling check if the nodes have a common ancestor
1427							siblingCheck( ap[i], bp[i] ) :
1428
1429							// Otherwise nodes in our document sort first
1430							ap[i] === preferredDoc ? -1 :
1431								bp[i] === preferredDoc ? 1 :
1432									0;
1433					};
1434
1435				return document;
1436			};
1437
1438			Sizzle.matches = function( expr, elements ) {
1439				return Sizzle( expr, null, null, elements );
1440			};
1441
1442			Sizzle.matchesSelector = function( elem, expr ) {
1443				// Set document vars if needed
1444				if ( ( elem.ownerDocument || elem ) !== document ) {
1445					setDocument( elem );
1446				}
1447
1448				// Make sure that attribute selectors are quoted
1449				expr = expr.replace( rattributeQuotes, "='$1']" );
1450
1451				if ( support.matchesSelector && documentIsHTML &&
1452					!compilerCache[ expr + " " ] &&
1453					( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1454					( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1455
1456					try {
1457						var ret = matches.call( elem, expr );
1458
1459						// IE 9's matchesSelector returns false on disconnected nodes
1460						if ( ret || support.disconnectedMatch ||
1461							// As well, disconnected nodes are said to be in a document
1462							// fragment in IE 9
1463							elem.document && elem.document.nodeType !== 11 ) {
1464							return ret;
1465						}
1466					} catch (e) {}
1467				}
1468
1469				return Sizzle( expr, document, null, [ elem ] ).length > 0;
1470			};
1471
1472			Sizzle.contains = function( context, elem ) {
1473				// Set document vars if needed
1474				if ( ( context.ownerDocument || context ) !== document ) {
1475					setDocument( context );
1476				}
1477				return contains( context, elem );
1478			};
1479
1480			Sizzle.attr = function( elem, name ) {
1481				// Set document vars if needed
1482				if ( ( elem.ownerDocument || elem ) !== document ) {
1483					setDocument( elem );
1484				}
1485
1486				var fn = Expr.attrHandle[ name.toLowerCase() ],
1487					// Don't get fooled by Object.prototype properties (jQuery #13807)
1488					val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1489						fn( elem, name, !documentIsHTML ) :
1490						undefined;
1491
1492				return val !== undefined ?
1493					val :
1494					support.attributes || !documentIsHTML ?
1495						elem.getAttribute( name ) :
1496						(val = elem.getAttributeNode(name)) && val.specified ?
1497							val.value :
1498							null;
1499			};
1500
1501			Sizzle.error = function( msg ) {
1502				throw new Error( "Syntax error, unrecognized expression: " + msg );
1503			};
1504
1505			/**
1506			 * Document sorting and removing duplicates
1507			 * @param {ArrayLike} results
1508			 */
1509			Sizzle.uniqueSort = function( results ) {
1510				var elem,
1511					duplicates = [],
1512					j = 0,
1513					i = 0;
1514
1515				// Unless we *know* we can detect duplicates, assume their presence
1516				hasDuplicate = !support.detectDuplicates;
1517				sortInput = !support.sortStable && results.slice( 0 );
1518				results.sort( sortOrder );
1519
1520				if ( hasDuplicate ) {
1521					while ( (elem = results[i++]) ) {
1522						if ( elem === results[ i ] ) {
1523							j = duplicates.push( i );
1524						}
1525					}
1526					while ( j-- ) {
1527						results.splice( duplicates[ j ], 1 );
1528					}
1529				}
1530
1531				// Clear input after sorting to release objects
1532				// See https://github.com/jquery/sizzle/pull/225
1533				sortInput = null;
1534
1535				return results;
1536			};
1537
1538			/**
1539			 * Utility function for retrieving the text value of an array of DOM nodes
1540			 * @param {Array|Element} elem
1541			 */
1542			getText = Sizzle.getText = function( elem ) {
1543				var node,
1544					ret = "",
1545					i = 0,
1546					nodeType = elem.nodeType;
1547
1548				if ( !nodeType ) {
1549					// If no nodeType, this is expected to be an array
1550					while ( (node = elem[i++]) ) {
vendor: 12,967 bytes, lines 1551-1949
1551						// Do not traverse comment nodes
1552						ret += getText( node );
1553					}
1554				} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1555					// Use textContent for elements
1556					// innerText usage removed for consistency of new lines (jQuery #11153)
1557					if ( typeof elem.textContent === "string" ) {
1558						return elem.textContent;
1559					} else {
1560						// Traverse its children
1561						for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1562							ret += getText( elem );
1563						}
1564					}
1565				} else if ( nodeType === 3 || nodeType === 4 ) {
1566					return elem.nodeValue;
1567				}
1568				// Do not include comment or processing instruction nodes
1569
1570				return ret;
1571			};
1572
1573			Expr = Sizzle.selectors = {
1574
1575				// Can be adjusted by the user
1576				cacheLength: 50,
1577
1578				createPseudo: markFunction,
1579
1580				match: matchExpr,
1581
1582				attrHandle: {},
1583
1584				find: {},
1585
1586				relative: {
1587					">": { dir: "parentNode", first: true },
1588					" ": { dir: "parentNode" },
1589					"+": { dir: "previousSibling", first: true },
1590					"~": { dir: "previousSibling" }
1591				},
1592
1593				preFilter: {
1594					"ATTR": function( match ) {
1595						match[1] = match[1].replace( runescape, funescape );
1596
1597						// Move the given value to match[3] whether quoted or unquoted
1598						match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1599
1600						if ( match[2] === "~=" ) {
1601							match[3] = " " + match[3] + " ";
1602						}
1603
1604						return match.slice( 0, 4 );
1605					},
1606
1607					"CHILD": function( match ) {
1608						/* matches from matchExpr["CHILD"]
1609				1 type (only|nth|...)
1610				2 what (child|of-type)
1611				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1612				4 xn-component of xn+y argument ([+-]?\d*n|)
1613				5 sign of xn-component
1614				6 x of xn-component
1615				7 sign of y-component
1616				8 y of y-component
1617			*/
1618						match[1] = match[1].toLowerCase();
1619
1620						if ( match[1].slice( 0, 3 ) === "nth" ) {
1621							// nth-* requires argument
1622							if ( !match[3] ) {
1623								Sizzle.error( match[0] );
1624							}
1625
1626							// numeric x and y parameters for Expr.filter.CHILD
1627							// remember that false/true cast respectively to 0/1
1628							match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1629							match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1630
1631							// other types prohibit arguments
1632						} else if ( match[3] ) {
1633							Sizzle.error( match[0] );
1634						}
1635
1636						return match;
1637					},
1638
1639					"PSEUDO": function( match ) {
1640						var excess,
1641							unquoted = !match[6] && match[2];
1642
1643						if ( matchExpr["CHILD"].test( match[0] ) ) {
1644							return null;
1645						}
1646
1647						// Accept quoted arguments as-is
1648						if ( match[3] ) {
1649							match[2] = match[4] || match[5] || "";
1650
1651							// Strip excess characters from unquoted arguments
1652						} else if ( unquoted && rpseudo.test( unquoted ) &&
1653							// Get excess from tokenize (recursively)
1654							(excess = tokenize( unquoted, true )) &&
1655							// advance to the next closing parenthesis
1656							(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1657
1658							// excess is a negative index
1659							match[0] = match[0].slice( 0, excess );
1660							match[2] = unquoted.slice( 0, excess );
1661						}
1662
1663						// Return only captures needed by the pseudo filter method (type and argument)
1664						return match.slice( 0, 3 );
1665					}
1666				},
1667
1668				filter: {
1669
1670					"TAG": function( nodeNameSelector ) {
1671						var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1672						return nodeNameSelector === "*" ?
1673							function() { return true; } :
1674							function( elem ) {
1675								return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1676							};
1677					},
1678
1679					"CLASS": function( className ) {
1680						var pattern = classCache[ className + " " ];
1681
1682						return pattern ||
1683							(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1684							classCache( className, function( elem ) {
1685								return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1686							});
1687					},
1688
1689					"ATTR": function( name, operator, check ) {
1690						return function( elem ) {
1691							var result = Sizzle.attr( elem, name );
1692
1693							if ( result == null ) {
1694								return operator === "!=";
1695							}
1696							if ( !operator ) {
1697								return true;
1698							}
1699
1700							result += "";
1701
1702							return operator === "=" ? result === check :
1703								operator === "!=" ? result !== check :
1704									operator === "^=" ? check && result.indexOf( check ) === 0 :
1705										operator === "*=" ? check && result.indexOf( check ) > -1 :
1706											operator === "$=" ? check && result.slice( -check.length ) === check :
1707												operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1708													operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1709														false;
1710						};
1711					},
1712
1713					"CHILD": function( type, what, argument, first, last ) {
1714						var simple = type.slice( 0, 3 ) !== "nth",
1715							forward = type.slice( -4 ) !== "last",
1716							ofType = what === "of-type";
1717
1718						return first === 1 && last === 0 ?
1719
1720							// Shortcut for :nth-*(n)
1721							function( elem ) {
1722								return !!elem.parentNode;
1723							} :
1724
1725							function( elem, context, xml ) {
1726								var cache, uniqueCache, outerCache, node, nodeIndex, start,
1727									dir = simple !== forward ? "nextSibling" : "previousSibling",
1728									parent = elem.parentNode,
1729									name = ofType && elem.nodeName.toLowerCase(),
1730									useCache = !xml && !ofType,
1731									diff = false;
1732
1733								if ( parent ) {
1734
1735									// :(first|last|only)-(child|of-type)
1736									if ( simple ) {
1737										while ( dir ) {
1738											node = elem;
1739											while ( (node = node[ dir ]) ) {
1740												if ( ofType ?
1741													node.nodeName.toLowerCase() === name :
1742													node.nodeType === 1 ) {
1743
1744													return false;
1745												}
1746											}
1747											// Reverse direction for :only-* (if we haven't yet done so)
1748											start = dir = type === "only" && !start && "nextSibling";
1749										}
1750										return true;
1751									}
1752
1753									start = [ forward ? parent.firstChild : parent.lastChild ];
1754
1755									// non-xml :nth-child(...) stores cache data on `parent`
1756									if ( forward && useCache ) {
1757
1758										// Seek `elem` from a previously-cached index
1759
1760										// ...in a gzip-friendly way
1761										node = parent;
1762										outerCache = node[ expando ] || (node[ expando ] = {});
1763
1764										// Support: IE <9 only
1765										// Defend against cloned attroperties (jQuery gh-1709)
1766										uniqueCache = outerCache[ node.uniqueID ] ||
1767											(outerCache[ node.uniqueID ] = {});
1768
1769										cache = uniqueCache[ type ] || [];
1770										nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1771										diff = nodeIndex && cache[ 2 ];
1772										node = nodeIndex && parent.childNodes[ nodeIndex ];
1773
1774										while ( (node = ++nodeIndex && node && node[ dir ] ||
1775
1776											// Fallback to seeking `elem` from the start
1777											(diff = nodeIndex = 0) || start.pop()) ) {
1778
1779											// When found, cache indexes on `parent` and break
1780											if ( node.nodeType === 1 && ++diff && node === elem ) {
1781												uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1782												break;
1783											}
1784										}
1785
1786									} else {
1787										// Use previously-cached element index if available
1788										if ( useCache ) {
1789											// ...in a gzip-friendly way
1790											node = elem;
1791											outerCache = node[ expando ] || (node[ expando ] = {});
1792
1793											// Support: IE <9 only
1794											// Defend against cloned attroperties (jQuery gh-1709)
1795											uniqueCache = outerCache[ node.uniqueID ] ||
1796												(outerCache[ node.uniqueID ] = {});
1797
1798											cache = uniqueCache[ type ] || [];
1799											nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1800											diff = nodeIndex;
1801										}
1802
1803										// xml :nth-child(...)
1804										// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1805										if ( diff === false ) {
1806											// Use the same loop as above to seek `elem` from the start
1807											while ( (node = ++nodeIndex && node && node[ dir ] ||
1808												(diff = nodeIndex = 0) || start.pop()) ) {
1809
1810												if ( ( ofType ?
1811														node.nodeName.toLowerCase() === name :
1812														node.nodeType === 1 ) &&
1813													++diff ) {
1814
1815													// Cache the index of each encountered element
1816													if ( useCache ) {
1817														outerCache = node[ expando ] || (node[ expando ] = {});
1818
1819														// Support: IE <9 only
1820														// Defend against cloned attroperties (jQuery gh-1709)
1821														uniqueCache = outerCache[ node.uniqueID ] ||
1822															(outerCache[ node.uniqueID ] = {});
1823
1824														uniqueCache[ type ] = [ dirruns, diff ];
1825													}
1826
1827													if ( node === elem ) {
1828														break;
1829													}
1830												}
1831											}
1832										}
1833									}
1834
1835									// Incorporate the offset, then check against cycle size
1836									diff -= last;
1837									return diff === first || ( diff % first === 0 && diff / first >= 0 );
1838								}
1839							};
1840					},
1841
1842					"PSEUDO": function( pseudo, argument ) {
1843						// pseudo-class names are case-insensitive
1844						// http://www.w3.org/TR/selectors/#pseudo-classes
1845						// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1846						// Remember that setFilters inherits from pseudos
1847						var args,
1848							fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1849								Sizzle.error( "unsupported pseudo: " + pseudo );
1850
1851						// The user may use createPseudo to indicate that
1852						// arguments are needed to create the filter function
1853						// just as Sizzle does
1854						if ( fn[ expando ] ) {
1855							return fn( argument );
1856						}
1857
1858						// But maintain support for old signatures
1859						if ( fn.length > 1 ) {
1860							args = [ pseudo, pseudo, "", argument ];
1861							return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1862								markFunction(function( seed, matches ) {
1863									var idx,
1864										matched = fn( seed, argument ),
1865										i = matched.length;
1866									while ( i-- ) {
1867										idx = indexOf( seed, matched[i] );
1868										seed[ idx ] = !( matches[ idx ] = matched[i] );
1869									}
1870								}) :
1871								function( elem ) {
1872									return fn( elem, 0, args );
1873								};
1874						}
1875
1876						return fn;
1877					}
1878				},
1879
1880				pseudos: {
1881					// Potentially complex pseudos
1882					"not": markFunction(function( selector ) {
1883						// Trim the selector passed to compile
1884						// to avoid treating leading and trailing
1885						// spaces as combinators
1886						var input = [],
1887							results = [],
1888							matcher = compile( selector.replace( rtrim, "$1" ) );
1889
1890						return matcher[ expando ] ?
1891							markFunction(function( seed, matches, context, xml ) {
1892								var elem,
1893									unmatched = matcher( seed, null, xml, [] ),
1894									i = seed.length;
1895
1896								// Match elements unmatched by `matcher`
1897								while ( i-- ) {
1898									if ( (elem = unmatched[i]) ) {
1899										seed[i] = !(matches[i] = elem);
1900									}
1901								}
1902							}) :
1903							function( elem, context, xml ) {
1904								input[0] = elem;
1905								matcher( input, null, xml, results );
1906								// Don't keep the element (issue #299)
1907								input[0] = null;
1908								return !results.pop();
1909							};
1910					}),
1911
1912					"has": markFunction(function( selector ) {
1913						return function( elem ) {
1914							return Sizzle( selector, elem ).length > 0;
1915						};
1916					}),
1917
1918					"contains": markFunction(function( text ) {
1919						text = text.replace( runescape, funescape );
1920						return function( elem ) {
1921							return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1922						};
1923					}),
1924
1925					// "Whether an element is represented by a :lang() selector
1926					// is based solely on the element's language value
1927					// being equal to the identifier C,
1928					// or beginning with the identifier C immediately followed by "-".
1929					// The matching of C against the element's language value is performed case-insensitively.
1930					// The identifier C does not have to be a valid language name."
1931					// http://www.w3.org/TR/selectors/#lang-pseudo
1932					"lang": markFunction( function( lang ) {
1933						// lang value must be a valid identifier
1934						if ( !ridentifier.test(lang || "") ) {
1935							Sizzle.error( "unsupported lang: " + lang );
1936						}
1937						lang = lang.replace( runescape, funescape ).toLowerCase();
1938						return function( elem ) {
1939							var elemLang;
1940							do {
1941								if ( (elemLang = documentIsHTML ?
1942									elem.lang :
1943									elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1944
1945									elemLang = elemLang.toLowerCase();
1946									return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1947								}
1948							} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1949							return false;
vendor: 4,960 bytes, lines 1950-2121
1950						};
1951					}),
1952
1953					// Miscellaneous
1954					"target": function( elem ) {
1955						var hash = window.location && window.location.hash;
1956						return hash && hash.slice( 1 ) === elem.id;
1957					},
1958
1959					"root": function( elem ) {
1960						return elem === docElem;
1961					},
1962
1963					"focus": function( elem ) {
1964						return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1965					},
1966
1967					// Boolean properties
1968					"enabled": function( elem ) {
1969						return elem.disabled === false;
1970					},
1971
1972					"disabled": function( elem ) {
1973						return elem.disabled === true;
1974					},
1975
1976					"checked": function( elem ) {
1977						// In CSS3, :checked should return both checked and selected elements
1978						// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1979						var nodeName = elem.nodeName.toLowerCase();
1980						return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1981					},
1982
1983					"selected": function( elem ) {
1984						// Accessing this property makes selected-by-default
1985						// options in Safari work properly
1986						if ( elem.parentNode ) {
1987							elem.parentNode.selectedIndex;
1988						}
1989
1990						return elem.selected === true;
1991					},
1992
1993					// Contents
1994					"empty": function( elem ) {
1995						// http://www.w3.org/TR/selectors/#empty-pseudo
1996						// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1997						//   but not by others (comment: 8; processing instruction: 7; etc.)
1998						// nodeType < 6 works because attributes (2) do not appear as children
1999						for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2000							if ( elem.nodeType < 6 ) {
2001								return false;
2002							}
2003						}
2004						return true;
2005					},
2006
2007					"parent": function( elem ) {
2008						return !Expr.pseudos["empty"]( elem );
2009					},
2010
2011					// Element/input types
2012					"header": function( elem ) {
2013						return rheader.test( elem.nodeName );
2014					},
2015
2016					"input": function( elem ) {
2017						return rinputs.test( elem.nodeName );
2018					},
2019
2020					"button": function( elem ) {
2021						var name = elem.nodeName.toLowerCase();
2022						return name === "input" && elem.type === "button" || name === "button";
2023					},
2024
2025					"text": function( elem ) {
2026						var attr;
2027						return elem.nodeName.toLowerCase() === "input" &&
2028							elem.type === "text" &&
2029
2030							// Support: IE<8
2031							// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2032							( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2033					},
2034
2035					// Position-in-collection
2036					"first": createPositionalPseudo(function() {
2037						return [ 0 ];
2038					}),
2039
2040					"last": createPositionalPseudo(function( matchIndexes, length ) {
2041						return [ length - 1 ];
2042					}),
2043
2044					"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2045						return [ argument < 0 ? argument + length : argument ];
2046					}),
2047
2048					"even": createPositionalPseudo(function( matchIndexes, length ) {
2049						var i = 0;
2050						for ( ; i < length; i += 2 ) {
2051							matchIndexes.push( i );
2052						}
2053						return matchIndexes;
2054					}),
2055
2056					"odd": createPositionalPseudo(function( matchIndexes, length ) {
2057						var i = 1;
2058						for ( ; i < length; i += 2 ) {
2059							matchIndexes.push( i );
2060						}
2061						return matchIndexes;
2062					}),
2063
2064					"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2065						var i = argument < 0 ? argument + length : argument;
2066						for ( ; --i >= 0; ) {
2067							matchIndexes.push( i );
2068						}
2069						return matchIndexes;
2070					}),
2071
2072					"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2073						var i = argument < 0 ? argument + length : argument;
2074						for ( ; ++i < length; ) {
2075							matchIndexes.push( i );
2076						}
2077						return matchIndexes;
2078					})
2079				}
2080			};
2081
2082			Expr.pseudos["nth"] = Expr.pseudos["eq"];
2083
2084// Add button/input type pseudos
2085			for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2086				Expr.pseudos[ i ] = createInputPseudo( i );
2087			}
2088			for ( i in { submit: true, reset: true } ) {
2089				Expr.pseudos[ i ] = createButtonPseudo( i );
2090			}
2091
2092// Easy API for creating new setFilters
2093			function setFilters() {}
2094			setFilters.prototype = Expr.filters = Expr.pseudos;
2095			Expr.setFilters = new setFilters();
2096
2097			tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2098				var matched, match, tokens, type,
2099					soFar, groups, preFilters,
2100					cached = tokenCache[ selector + " " ];
2101
2102				if ( cached ) {
2103					return parseOnly ? 0 : cached.slice( 0 );
2104				}
2105
2106				soFar = selector;
2107				groups = [];
2108				preFilters = Expr.preFilter;
2109
2110				while ( soFar ) {
2111
2112					// Comma and first run
2113					if ( !matched || (match = rcomma.exec( soFar )) ) {
2114						if ( match ) {
2115							// Don't consume trailing commas as valid
2116							soFar = soFar.slice( match[0].length ) || soFar;
2117						}
2118						groups.push( (tokens = []) );
2119					}
2120
2121					matched = false;
vendor: 4,193 bytes, lines 2122-2276
2122
2123					// Combinators
2124					if ( (match = rcombinators.exec( soFar )) ) {
2125						matched = match.shift();
2126						tokens.push({
2127							value: matched,
2128							// Cast descendant combinators to space
2129							type: match[0].replace( rtrim, " " )
2130						});
2131						soFar = soFar.slice( matched.length );
2132					}
2133
2134					// Filters
2135					for ( type in Expr.filter ) {
2136						if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2137							(match = preFilters[ type ]( match ))) ) {
2138							matched = match.shift();
2139							tokens.push({
2140								value: matched,
2141								type: type,
2142								matches: match
2143							});
2144							soFar = soFar.slice( matched.length );
2145						}
2146					}
2147
2148					if ( !matched ) {
2149						break;
2150					}
2151				}
2152
2153				// Return the length of the invalid excess
2154				// if we're just parsing
2155				// Otherwise, throw an error or return tokens
2156				return parseOnly ?
2157					soFar.length :
2158					soFar ?
2159						Sizzle.error( selector ) :
2160						// Cache the tokens
2161						tokenCache( selector, groups ).slice( 0 );
2162			};
2163
2164			function toSelector( tokens ) {
2165				var i = 0,
2166					len = tokens.length,
2167					selector = "";
2168				for ( ; i < len; i++ ) {
2169					selector += tokens[i].value;
2170				}
2171				return selector;
2172			}
2173
2174			function addCombinator( matcher, combinator, base ) {
2175				var dir = combinator.dir,
2176					checkNonElements = base && dir === "parentNode",
2177					doneName = done++;
2178
2179				return combinator.first ?
2180					// Check against closest ancestor/preceding element
2181					function( elem, context, xml ) {
2182						while ( (elem = elem[ dir ]) ) {
2183							if ( elem.nodeType === 1 || checkNonElements ) {
2184								return matcher( elem, context, xml );
2185							}
2186						}
2187					} :
2188
2189					// Check against all ancestor/preceding elements
2190					function( elem, context, xml ) {
2191						var oldCache, uniqueCache, outerCache,
2192							newCache = [ dirruns, doneName ];
2193
2194						// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2195						if ( xml ) {
2196							while ( (elem = elem[ dir ]) ) {
2197								if ( elem.nodeType === 1 || checkNonElements ) {
2198									if ( matcher( elem, context, xml ) ) {
2199										return true;
2200									}
2201								}
2202							}
2203						} else {
2204							while ( (elem = elem[ dir ]) ) {
2205								if ( elem.nodeType === 1 || checkNonElements ) {
2206									outerCache = elem[ expando ] || (elem[ expando ] = {});
2207
2208									// Support: IE <9 only
2209									// Defend against cloned attroperties (jQuery gh-1709)
2210									uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2211
2212									if ( (oldCache = uniqueCache[ dir ]) &&
2213										oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2214
2215										// Assign to newCache so results back-propagate to previous elements
2216										return (newCache[ 2 ] = oldCache[ 2 ]);
2217									} else {
2218										// Reuse newcache so results back-propagate to previous elements
2219										uniqueCache[ dir ] = newCache;
2220
2221										// A match means we're done; a fail means we have to keep checking
2222										if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2223											return true;
2224										}
2225									}
2226								}
2227							}
2228						}
2229					};
2230			}
2231
2232			function elementMatcher( matchers ) {
2233				return matchers.length > 1 ?
2234					function( elem, context, xml ) {
2235						var i = matchers.length;
2236						while ( i-- ) {
2237							if ( !matchers[i]( elem, context, xml ) ) {
2238								return false;
2239							}
2240						}
2241						return true;
2242					} :
2243					matchers[0];
2244			}
2245
2246			function multipleContexts( selector, contexts, results ) {
2247				var i = 0,
2248					len = contexts.length;
2249				for ( ; i < len; i++ ) {
2250					Sizzle( selector, contexts[i], results );
2251				}
2252				return results;
2253			}
2254
2255			function condense( unmatched, map, filter, context, xml ) {
2256				var elem,
2257					newUnmatched = [],
2258					i = 0,
2259					len = unmatched.length,
2260					mapped = map != null;
2261
2262				for ( ; i < len; i++ ) {
2263					if ( (elem = unmatched[i]) ) {
2264						if ( !filter || filter( elem, context, xml ) ) {
2265							newUnmatched.push( elem );
2266							if ( mapped ) {
2267								map.push( i );
2268							}
2269						}
2270					}
2271				}
2272
2273				return newUnmatched;
2274			}
2275
2276			function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
vendor: 11,495 bytes, lines 2277-2618
2277				if ( postFilter && !postFilter[ expando ] ) {
2278					postFilter = setMatcher( postFilter );
2279				}
2280				if ( postFinder && !postFinder[ expando ] ) {
2281					postFinder = setMatcher( postFinder, postSelector );
2282				}
2283				return markFunction(function( seed, results, context, xml ) {
2284					var temp, i, elem,
2285						preMap = [],
2286						postMap = [],
2287						preexisting = results.length,
2288
2289						// Get initial elements from seed or context
2290						elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2291
2292						// Prefilter to get matcher input, preserving a map for seed-results synchronization
2293						matcherIn = preFilter && ( seed || !selector ) ?
2294							condense( elems, preMap, preFilter, context, xml ) :
2295							elems,
2296
2297						matcherOut = matcher ?
2298							// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2299							postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2300
2301								// ...intermediate processing is necessary
2302								[] :
2303
2304								// ...otherwise use results directly
2305								results :
2306							matcherIn;
2307
2308					// Find primary matches
2309					if ( matcher ) {
2310						matcher( matcherIn, matcherOut, context, xml );
2311					}
2312
2313					// Apply postFilter
2314					if ( postFilter ) {
2315						temp = condense( matcherOut, postMap );
2316						postFilter( temp, [], context, xml );
2317
2318						// Un-match failing elements by moving them back to matcherIn
2319						i = temp.length;
2320						while ( i-- ) {
2321							if ( (elem = temp[i]) ) {
2322								matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2323							}
2324						}
2325					}
2326
2327					if ( seed ) {
2328						if ( postFinder || preFilter ) {
2329							if ( postFinder ) {
2330								// Get the final matcherOut by condensing this intermediate into postFinder contexts
2331								temp = [];
2332								i = matcherOut.length;
2333								while ( i-- ) {
2334									if ( (elem = matcherOut[i]) ) {
2335										// Restore matcherIn since elem is not yet a final match
2336										temp.push( (matcherIn[i] = elem) );
2337									}
2338								}
2339								postFinder( null, (matcherOut = []), temp, xml );
2340							}
2341
2342							// Move matched elements from seed to results to keep them synchronized
2343							i = matcherOut.length;
2344							while ( i-- ) {
2345								if ( (elem = matcherOut[i]) &&
2346									(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2347
2348									seed[temp] = !(results[temp] = elem);
2349								}
2350							}
2351						}
2352
2353						// Add elements to results, through postFinder if defined
2354					} else {
2355						matcherOut = condense(
2356							matcherOut === results ?
2357								matcherOut.splice( preexisting, matcherOut.length ) :
2358								matcherOut
2359						);
2360						if ( postFinder ) {
2361							postFinder( null, results, matcherOut, xml );
2362						} else {
2363							push.apply( results, matcherOut );
2364						}
2365					}
2366				});
2367			}
2368
2369			function matcherFromTokens( tokens ) {
2370				var checkContext, matcher, j,
2371					len = tokens.length,
2372					leadingRelative = Expr.relative[ tokens[0].type ],
2373					implicitRelative = leadingRelative || Expr.relative[" "],
2374					i = leadingRelative ? 1 : 0,
2375
2376					// The foundational matcher ensures that elements are reachable from top-level context(s)
2377					matchContext = addCombinator( function( elem ) {
2378						return elem === checkContext;
2379					}, implicitRelative, true ),
2380					matchAnyContext = addCombinator( function( elem ) {
2381						return indexOf( checkContext, elem ) > -1;
2382					}, implicitRelative, true ),
2383					matchers = [ function( elem, context, xml ) {
2384						var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2385							(checkContext = context).nodeType ?
2386								matchContext( elem, context, xml ) :
2387								matchAnyContext( elem, context, xml ) );
2388						// Avoid hanging onto element (issue #299)
2389						checkContext = null;
2390						return ret;
2391					} ];
2392
2393				for ( ; i < len; i++ ) {
2394					if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2395						matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2396					} else {
2397						matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2398
2399						// Return special upon seeing a positional matcher
2400						if ( matcher[ expando ] ) {
2401							// Find the next relative operator (if any) for proper handling
2402							j = ++i;
2403							for ( ; j < len; j++ ) {
2404								if ( Expr.relative[ tokens[j].type ] ) {
2405									break;
2406								}
2407							}
2408							return setMatcher(
2409								i > 1 && elementMatcher( matchers ),
2410								i > 1 && toSelector(
2411									// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2412									tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2413								).replace( rtrim, "$1" ),
2414								matcher,
2415								i < j && matcherFromTokens( tokens.slice( i, j ) ),
2416								j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2417								j < len && toSelector( tokens )
2418							);
2419						}
2420						matchers.push( matcher );
2421					}
2422				}
2423
2424				return elementMatcher( matchers );
2425			}
2426
2427			function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2428				var bySet = setMatchers.length > 0,
2429					byElement = elementMatchers.length > 0,
2430					superMatcher = function( seed, context, xml, results, outermost ) {
2431						var elem, j, matcher,
2432							matchedCount = 0,
2433							i = "0",
2434							unmatched = seed && [],
2435							setMatched = [],
2436							contextBackup = outermostContext,
2437							// We must always have either seed elements or outermost context
2438							elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2439							// Use integer dirruns iff this is the outermost matcher
2440							dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2441							len = elems.length;
2442
2443						if ( outermost ) {
2444							outermostContext = context === document || context || outermost;
2445						}
2446
2447						// Add elements passing elementMatchers directly to results
2448						// Support: IE<9, Safari
2449						// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2450						for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2451							if ( byElement && elem ) {
2452								j = 0;
2453								if ( !context && elem.ownerDocument !== document ) {
2454									setDocument( elem );
2455									xml = !documentIsHTML;
2456								}
2457								while ( (matcher = elementMatchers[j++]) ) {
2458									if ( matcher( elem, context || document, xml) ) {
2459										results.push( elem );
2460										break;
2461									}
2462								}
2463								if ( outermost ) {
2464									dirruns = dirrunsUnique;
2465								}
2466							}
2467
2468							// Track unmatched elements for set filters
2469							if ( bySet ) {
2470								// They will have gone through all possible matchers
2471								if ( (elem = !matcher && elem) ) {
2472									matchedCount--;
2473								}
2474
2475								// Lengthen the array for every element, matched or not
2476								if ( seed ) {
2477									unmatched.push( elem );
2478								}
2479							}
2480						}
2481
2482						// `i` is now the count of elements visited above, and adding it to `matchedCount`
2483						// makes the latter nonnegative.
2484						matchedCount += i;
2485
2486						// Apply set filters to unmatched elements
2487						// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2488						// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2489						// no element matchers and no seed.
2490						// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2491						// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2492						// numerically zero.
2493						if ( bySet && i !== matchedCount ) {
2494							j = 0;
2495							while ( (matcher = setMatchers[j++]) ) {
2496								matcher( unmatched, setMatched, context, xml );
2497							}
2498
2499							if ( seed ) {
2500								// Reintegrate element matches to eliminate the need for sorting
2501								if ( matchedCount > 0 ) {
2502									while ( i-- ) {
2503										if ( !(unmatched[i] || setMatched[i]) ) {
2504											setMatched[i] = pop.call( results );
2505										}
2506									}
2507								}
2508
2509								// Discard index placeholder values to get only actual matches
2510								setMatched = condense( setMatched );
2511							}
2512
2513							// Add matches to results
2514							push.apply( results, setMatched );
2515
2516							// Seedless set matches succeeding multiple successful matchers stipulate sorting
2517							if ( outermost && !seed && setMatched.length > 0 &&
2518								( matchedCount + setMatchers.length ) > 1 ) {
2519
2520								Sizzle.uniqueSort( results );
2521							}
2522						}
2523
2524						// Override manipulation of globals by nested matchers
2525						if ( outermost ) {
2526							dirruns = dirrunsUnique;
2527							outermostContext = contextBackup;
2528						}
2529
2530						return unmatched;
2531					};
2532
2533				return bySet ?
2534					markFunction( superMatcher ) :
2535					superMatcher;
2536			}
2537
2538			compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2539				var i,
2540					setMatchers = [],
2541					elementMatchers = [],
2542					cached = compilerCache[ selector + " " ];
2543
2544				if ( !cached ) {
2545					// Generate a function of recursive functions that can be used to check each element
2546					if ( !match ) {
2547						match = tokenize( selector );
2548					}
2549					i = match.length;
2550					while ( i-- ) {
2551						cached = matcherFromTokens( match[i] );
2552						if ( cached[ expando ] ) {
2553							setMatchers.push( cached );
2554						} else {
2555							elementMatchers.push( cached );
2556						}
2557					}
2558
2559					// Cache the compiled function
2560					cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2561
2562					// Save selector and tokenization
2563					cached.selector = selector;
2564				}
2565				return cached;
2566			};
2567
2568			/**
2569			 * A low-level selection function that works with Sizzle's compiled
2570			 *  selector functions
2571			 * @param {String|Function} selector A selector or a pre-compiled
2572			 *  selector function built with Sizzle.compile
2573			 * @param {Element} context
2574			 * @param {Array} [results]
2575			 * @param {Array} [seed] A set of elements to match against
2576			 */
2577			select = Sizzle.select = function( selector, context, results, seed ) {
2578				var i, tokens, token, type, find,
2579					compiled = typeof selector === "function" && selector,
2580					match = !seed && tokenize( (selector = compiled.selector || selector) );
2581
2582				results = results || [];
2583
2584				// Try to minimize operations if there is only one selector in the list and no seed
2585				// (the latter of which guarantees us context)
2586				if ( match.length === 1 ) {
2587
2588					// Reduce context if the leading compound selector is an ID
2589					tokens = match[0] = match[0].slice( 0 );
2590					if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2591						support.getById && context.nodeType === 9 && documentIsHTML &&
2592						Expr.relative[ tokens[1].type ] ) {
2593
2594						context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2595						if ( !context ) {
2596							return results;
2597
2598							// Precompiled matchers will still verify ancestry, so step up a level
2599						} else if ( compiled ) {
2600							context = context.parentNode;
2601						}
2602
2603						selector = selector.slice( tokens.shift().value.length );
2604					}
2605
2606					// Fetch a seed set for right-to-left matching
2607					i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2608					while ( i-- ) {
2609						token = tokens[i];
2610
2611						// Abort if we hit a combinator
2612						if ( Expr.relative[ (type = token.type) ] ) {
2613							break;
2614						}
2615						if ( (find = Expr.find[ type ]) ) {
2616							// Search, expanding context for leading sibling combinators
2617							if ( (seed = find(
2618								token.matches[0].replace( runescape, funescape ),
vendor: 5,031 bytes, lines 2619-2815
2619								rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2620							)) ) {
2621
2622								// If seed is empty or no tokens remain, we can return early
2623								tokens.splice( i, 1 );
2624								selector = seed.length && toSelector( tokens );
2625								if ( !selector ) {
2626									push.apply( results, seed );
2627									return results;
2628								}
2629
2630								break;
2631							}
2632						}
2633					}
2634				}
2635
2636				// Compile and execute a filtering function if one is not provided
2637				// Provide `match` to avoid retokenization if we modified the selector above
2638				( compiled || compile( selector, match ) )(
2639					seed,
2640					context,
2641					!documentIsHTML,
2642					results,
2643					!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2644				);
2645				return results;
2646			};
2647
2648// One-time assignments
2649
2650// Sort stability
2651			support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2652
2653// Support: Chrome 14-35+
2654// Always assume duplicates if they aren't passed to the comparison function
2655			support.detectDuplicates = !!hasDuplicate;
2656
2657// Initialize against the default document
2658			setDocument();
2659
2660// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2661// Detached nodes confoundingly follow *each other*
2662			support.sortDetached = assert(function( div1 ) {
2663				// Should return 1, but returns 4 (following)
2664				return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2665			});
2666
2667// Support: IE<8
2668// Prevent attribute/property "interpolation"
2669// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2670			if ( !assert(function( div ) {
2671				div.innerHTML = "<a href='#'></a>";
2672				return div.firstChild.getAttribute("href") === "#" ;
2673			}) ) {
2674				addHandle( "type|href|height|width", function( elem, name, isXML ) {
2675					if ( !isXML ) {
2676						return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2677					}
2678				});
2679			}
2680
2681// Support: IE<9
2682// Use defaultValue in place of getAttribute("value")
2683			if ( !support.attributes || !assert(function( div ) {
2684				div.innerHTML = "<input/>";
2685				div.firstChild.setAttribute( "value", "" );
2686				return div.firstChild.getAttribute( "value" ) === "";
2687			}) ) {
2688				addHandle( "value", function( elem, name, isXML ) {
2689					if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2690						return elem.defaultValue;
2691					}
2692				});
2693			}
2694
2695// Support: IE<9
2696// Use getAttributeNode to fetch booleans when getAttribute lies
2697			if ( !assert(function( div ) {
2698				return div.getAttribute("disabled") == null;
2699			}) ) {
2700				addHandle( booleans, function( elem, name, isXML ) {
2701					var val;
2702					if ( !isXML ) {
2703						return elem[ name ] === true ? name.toLowerCase() :
2704							(val = elem.getAttributeNode( name )) && val.specified ?
2705								val.value :
2706								null;
2707					}
2708				});
2709			}
2710
2711			return Sizzle;
2712
2713		})( window );
2714
2715
2716
2717	jQuery.find = Sizzle;
2718	jQuery.expr = Sizzle.selectors;
2719	jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2720	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2721	jQuery.text = Sizzle.getText;
2722	jQuery.isXMLDoc = Sizzle.isXML;
2723	jQuery.contains = Sizzle.contains;
2724
2725
2726
2727	var dir = function( elem, dir, until ) {
2728		var matched = [],
2729			truncate = until !== undefined;
2730
2731		while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2732			if ( elem.nodeType === 1 ) {
2733				if ( truncate && jQuery( elem ).is( until ) ) {
2734					break;
2735				}
2736				matched.push( elem );
2737			}
2738		}
2739		return matched;
2740	};
2741
2742
2743	var siblings = function( n, elem ) {
2744		var matched = [];
2745
2746		for ( ; n; n = n.nextSibling ) {
2747			if ( n.nodeType === 1 && n !== elem ) {
2748				matched.push( n );
2749			}
2750		}
2751
2752		return matched;
2753	};
2754
2755
2756	var rneedsContext = jQuery.expr.match.needsContext;
2757
2758	var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2759
2760
2761
2762	var risSimple = /^.[^:#\[\.,]*$/;
2763
2764// Implement the identical functionality for filter and not
2765	function winnow( elements, qualifier, not ) {
2766		if ( jQuery.isFunction( qualifier ) ) {
2767			return jQuery.grep( elements, function( elem, i ) {
2768				/* jshint -W018 */
2769				return !!qualifier.call( elem, i, elem ) !== not;
2770			} );
2771
2772		}
2773
2774		if ( qualifier.nodeType ) {
2775			return jQuery.grep( elements, function( elem ) {
2776				return ( elem === qualifier ) !== not;
2777			} );
2778
2779		}
2780
2781		if ( typeof qualifier === "string" ) {
2782			if ( risSimple.test( qualifier ) ) {
2783				return jQuery.filter( qualifier, elements, not );
2784			}
2785
2786			qualifier = jQuery.filter( qualifier, elements );
2787		}
2788
2789		return jQuery.grep( elements, function( elem ) {
2790			return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
2791		} );
2792	}
2793
2794	jQuery.filter = function( expr, elems, not ) {
2795		var elem = elems[ 0 ];
2796
2797		if ( not ) {
2798			expr = ":not(" + expr + ")";
2799		}
2800
2801		return elems.length === 1 && elem.nodeType === 1 ?
2802			jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2803			jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2804				return elem.nodeType === 1;
2805			} ) );
2806	};
2807
2808	jQuery.fn.extend( {
2809		find: function( selector ) {
2810			var i,
2811				ret = [],
2812				self = this,
2813				len = self.length;
2814
2815			if ( typeof selector !== "string" ) {
vendor: 5,085 bytes, lines 2816-2997
2816				return this.pushStack( jQuery( selector ).filter( function() {
2817					for ( i = 0; i < len; i++ ) {
2818						if ( jQuery.contains( self[ i ], this ) ) {
2819							return true;
2820						}
2821					}
2822				} ) );
2823			}
2824
2825			for ( i = 0; i < len; i++ ) {
2826				jQuery.find( selector, self[ i ], ret );
2827			}
2828
2829			// Needed because $( selector, context ) becomes $( context ).find( selector )
2830			ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2831			ret.selector = this.selector ? this.selector + " " + selector : selector;
2832			return ret;
2833		},
2834		filter: function( selector ) {
2835			return this.pushStack( winnow( this, selector || [], false ) );
2836		},
2837		not: function( selector ) {
2838			return this.pushStack( winnow( this, selector || [], true ) );
2839		},
2840		is: function( selector ) {
2841			return !!winnow(
2842				this,
2843
2844				// If this is a positional/relative selector, check membership in the returned set
2845				// so $("p:first").is("p:last") won't return true for a doc with two "p".
2846				typeof selector === "string" && rneedsContext.test( selector ) ?
2847					jQuery( selector ) :
2848					selector || [],
2849				false
2850			).length;
2851		}
2852	} );
2853
2854
2855// Initialize a jQuery object
2856
2857
2858// A central reference to the root jQuery(document)
2859	var rootjQuery,
2860
2861		// A simple way to check for HTML strings
2862		// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2863		// Strict HTML recognition (#11290: must start with <)
2864		rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2865
2866		init = jQuery.fn.init = function( selector, context, root ) {
2867			var match, elem;
2868
2869			// HANDLE: $(""), $(null), $(undefined), $(false)
2870			if ( !selector ) {
2871				return this;
2872			}
2873
2874			// init accepts an alternate rootjQuery
2875			// so migrate can support jQuery.sub (gh-2101)
2876			root = root || rootjQuery;
2877
2878			// Handle HTML strings
2879			if ( typeof selector === "string" ) {
2880				if ( selector.charAt( 0 ) === "<" &&
2881					selector.charAt( selector.length - 1 ) === ">" &&
2882					selector.length >= 3 ) {
2883
2884					// Assume that strings that start and end with <> are HTML and skip the regex check
2885					match = [ null, selector, null ];
2886
2887				} else {
2888					match = rquickExpr.exec( selector );
2889				}
2890
2891				// Match html or make sure no context is specified for #id
2892				if ( match && ( match[ 1 ] || !context ) ) {
2893
2894					// HANDLE: $(html) -> $(array)
2895					if ( match[ 1 ] ) {
2896						context = context instanceof jQuery ? context[ 0 ] : context;
2897
2898						// scripts is true for back-compat
2899						// Intentionally let the error be thrown if parseHTML is not present
2900						jQuery.merge( this, jQuery.parseHTML(
2901							match[ 1 ],
2902							context && context.nodeType ? context.ownerDocument || context : document,
2903							true
2904						) );
2905
2906						// HANDLE: $(html, props)
2907						if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2908							for ( match in context ) {
2909
2910								// Properties of context are called as methods if possible
2911								if ( jQuery.isFunction( this[ match ] ) ) {
2912									this[ match ]( context[ match ] );
2913
2914									// ...and otherwise set as attributes
2915								} else {
2916									this.attr( match, context[ match ] );
2917								}
2918							}
2919						}
2920
2921						return this;
2922
2923						// HANDLE: $(#id)
2924					} else {
2925						elem = document.getElementById( match[ 2 ] );
2926
2927						// Check parentNode to catch when Blackberry 4.6 returns
2928						// nodes that are no longer in the document #6963
2929						if ( elem && elem.parentNode ) {
2930
2931							// Handle the case where IE and Opera return items
2932							// by name instead of ID
2933							if ( elem.id !== match[ 2 ] ) {
2934								return rootjQuery.find( selector );
2935							}
2936
2937							// Otherwise, we inject the element directly into the jQuery object
2938							this.length = 1;
2939							this[ 0 ] = elem;
2940						}
2941
2942						this.context = document;
2943						this.selector = selector;
2944						return this;
2945					}
2946
2947					// HANDLE: $(expr, $(...))
2948				} else if ( !context || context.jquery ) {
2949					return ( context || root ).find( selector );
2950
2951					// HANDLE: $(expr, context)
2952					// (which is just equivalent to: $(context).find(expr)
2953				} else {
2954					return this.constructor( context ).find( selector );
2955				}
2956
2957				// HANDLE: $(DOMElement)
2958			} else if ( selector.nodeType ) {
2959				this.context = this[ 0 ] = selector;
2960				this.length = 1;
2961				return this;
2962
2963				// HANDLE: $(function)
2964				// Shortcut for document ready
2965			} else if ( jQuery.isFunction( selector ) ) {
2966				return typeof root.ready !== "undefined" ?
2967					root.ready( selector ) :
2968
2969					// Execute immediately if ready is not present
2970					selector( jQuery );
2971			}
2972
2973			if ( selector.selector !== undefined ) {
2974				this.selector = selector.selector;
2975				this.context = selector.context;
2976			}
2977
2978			return jQuery.makeArray( selector, this );
2979		};
2980
2981// Give the init function the jQuery prototype for later instantiation
2982	init.prototype = jQuery.fn;
2983
2984// Initialize central reference
2985	rootjQuery = jQuery( document );
2986
2987
2988	var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2989
2990		// methods guaranteed to produce a unique set when starting from a unique set
2991		guaranteedUnique = {
2992			children: true,
2993			contents: true,
2994			next: true,
2995			prev: true
2996		};
2997
vendor: 13,760 bytes, lines 2998-3527
2998	jQuery.fn.extend( {
2999		has: function( target ) {
3000			var i,
3001				targets = jQuery( target, this ),
3002				len = targets.length;
3003
3004			return this.filter( function() {
3005				for ( i = 0; i < len; i++ ) {
3006					if ( jQuery.contains( this, targets[ i ] ) ) {
3007						return true;
3008					}
3009				}
3010			} );
3011		},
3012
3013		closest: function( selectors, context ) {
3014			var cur,
3015				i = 0,
3016				l = this.length,
3017				matched = [],
3018				pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
3019					jQuery( selectors, context || this.context ) :
3020					0;
3021
3022			for ( ; i < l; i++ ) {
3023				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3024
3025					// Always skip document fragments
3026					if ( cur.nodeType < 11 && ( pos ?
3027						pos.index( cur ) > -1 :
3028
3029						// Don't pass non-elements to Sizzle
3030						cur.nodeType === 1 &&
3031						jQuery.find.matchesSelector( cur, selectors ) ) ) {
3032
3033						matched.push( cur );
3034						break;
3035					}
3036				}
3037			}
3038
3039			return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3040		},
3041
3042		// Determine the position of an element within
3043		// the matched set of elements
3044		index: function( elem ) {
3045
3046			// No argument, return index in parent
3047			if ( !elem ) {
3048				return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3049			}
3050
3051			// index in selector
3052			if ( typeof elem === "string" ) {
3053				return jQuery.inArray( this[ 0 ], jQuery( elem ) );
3054			}
3055
3056			// Locate the position of the desired element
3057			return jQuery.inArray(
3058
3059				// If it receives a jQuery object, the first element is used
3060				elem.jquery ? elem[ 0 ] : elem, this );
3061		},
3062
3063		add: function( selector, context ) {
3064			return this.pushStack(
3065				jQuery.uniqueSort(
3066					jQuery.merge( this.get(), jQuery( selector, context ) )
3067				)
3068			);
3069		},
3070
3071		addBack: function( selector ) {
3072			return this.add( selector == null ?
3073				this.prevObject : this.prevObject.filter( selector )
3074			);
3075		}
3076	} );
3077
3078	function sibling( cur, dir ) {
3079		do {
3080			cur = cur[ dir ];
3081		} while ( cur && cur.nodeType !== 1 );
3082
3083		return cur;
3084	}
3085
3086	jQuery.each( {
3087		parent: function( elem ) {
3088			var parent = elem.parentNode;
3089			return parent && parent.nodeType !== 11 ? parent : null;
3090		},
3091		parents: function( elem ) {
3092			return dir( elem, "parentNode" );
3093		},
3094		parentsUntil: function( elem, i, until ) {
3095			return dir( elem, "parentNode", until );
3096		},
3097		next: function( elem ) {
3098			return sibling( elem, "nextSibling" );
3099		},
3100		prev: function( elem ) {
3101			return sibling( elem, "previousSibling" );
3102		},
3103		nextAll: function( elem ) {
3104			return dir( elem, "nextSibling" );
3105		},
3106		prevAll: function( elem ) {
3107			return dir( elem, "previousSibling" );
3108		},
3109		nextUntil: function( elem, i, until ) {
3110			return dir( elem, "nextSibling", until );
3111		},
3112		prevUntil: function( elem, i, until ) {
3113			return dir( elem, "previousSibling", until );
3114		},
3115		siblings: function( elem ) {
3116			return siblings( ( elem.parentNode || {} ).firstChild, elem );
3117		},
3118		children: function( elem ) {
3119			return siblings( elem.firstChild );
3120		},
3121		contents: function( elem ) {
3122			return jQuery.nodeName( elem, "iframe" ) ?
3123				elem.contentDocument || elem.contentWindow.document :
3124				jQuery.merge( [], elem.childNodes );
3125		}
3126	}, function( name, fn ) {
3127		jQuery.fn[ name ] = function( until, selector ) {
3128			var ret = jQuery.map( this, fn, until );
3129
3130			if ( name.slice( -5 ) !== "Until" ) {
3131				selector = until;
3132			}
3133
3134			if ( selector && typeof selector === "string" ) {
3135				ret = jQuery.filter( selector, ret );
3136			}
3137
3138			if ( this.length > 1 ) {
3139
3140				// Remove duplicates
3141				if ( !guaranteedUnique[ name ] ) {
3142					ret = jQuery.uniqueSort( ret );
3143				}
3144
3145				// Reverse order for parents* and prev-derivatives
3146				if ( rparentsprev.test( name ) ) {
3147					ret = ret.reverse();
3148				}
3149			}
3150
3151			return this.pushStack( ret );
3152		};
3153	} );
3154	var rnotwhite = ( /\S+/g );
3155
3156
3157
3158// Convert String-formatted options into Object-formatted ones
3159	function createOptions( options ) {
3160		var object = {};
3161		jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3162			object[ flag ] = true;
3163		} );
3164		return object;
3165	}
3166
3167	/*
3168 * Create a callback list using the following parameters:
3169 *
3170 *	options: an optional list of space-separated options that will change how
3171 *			the callback list behaves or a more traditional option object
3172 *
3173 * By default a callback list will act like an event callback list and can be
3174 * "fired" multiple times.
3175 *
3176 * Possible options:
3177 *
3178 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3179 *
3180 *	memory:			will keep track of previous values and will call any callback added
3181 *					after the list has been fired right away with the latest "memorized"
3182 *					values (like a Deferred)
3183 *
3184 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3185 *
3186 *	stopOnFalse:	interrupt callings when a callback returns false
3187 *
3188 */
3189	jQuery.Callbacks = function( options ) {
3190
3191		// Convert options from String-formatted to Object-formatted if needed
3192		// (we check in cache first)
3193		options = typeof options === "string" ?
3194			createOptions( options ) :
3195			jQuery.extend( {}, options );
3196
3197		var // Flag to know if list is currently firing
3198			firing,
3199
3200			// Last fire value for non-forgettable lists
3201			memory,
3202
3203			// Flag to know if list was already fired
3204			fired,
3205
3206			// Flag to prevent firing
3207			locked,
3208
3209			// Actual callback list
3210			list = [],
3211
3212			// Queue of execution data for repeatable lists
3213			queue = [],
3214
3215			// Index of currently firing callback (modified by add/remove as needed)
3216			firingIndex = -1,
3217
3218			// Fire callbacks
3219			fire = function() {
3220
3221				// Enforce single-firing
3222				locked = options.once;
3223
3224				// Execute callbacks for all pending executions,
3225				// respecting firingIndex overrides and runtime changes
3226				fired = firing = true;
3227				for ( ; queue.length; firingIndex = -1 ) {
3228					memory = queue.shift();
3229					while ( ++firingIndex < list.length ) {
3230
3231						// Run callback and check for early termination
3232						if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3233							options.stopOnFalse ) {
3234
3235							// Jump to end and forget the data so .add doesn't re-fire
3236							firingIndex = list.length;
3237							memory = false;
3238						}
3239					}
3240				}
3241
3242				// Forget the data if we're done with it
3243				if ( !options.memory ) {
3244					memory = false;
3245				}
3246
3247				firing = false;
3248
3249				// Clean up if we're done firing for good
3250				if ( locked ) {
3251
3252					// Keep an empty list if we have data for future add calls
3253					if ( memory ) {
3254						list = [];
3255
3256						// Otherwise, this object is spent
3257					} else {
3258						list = "";
3259					}
3260				}
3261			},
3262
3263			// Actual Callbacks object
3264			self = {
3265
3266				// Add a callback or a collection of callbacks to the list
3267				add: function() {
3268					if ( list ) {
3269
3270						// If we have memory from a past run, we should fire after adding
3271						if ( memory && !firing ) {
3272							firingIndex = list.length - 1;
3273							queue.push( memory );
3274						}
3275
3276						( function add( args ) {
3277							jQuery.each( args, function( _, arg ) {
3278								if ( jQuery.isFunction( arg ) ) {
3279									if ( !options.unique || !self.has( arg ) ) {
3280										list.push( arg );
3281									}
3282								} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3283
3284									// Inspect recursively
3285									add( arg );
3286								}
3287							} );
3288						} )( arguments );
3289
3290						if ( memory && !firing ) {
3291							fire();
3292						}
3293					}
3294					return this;
3295				},
3296
3297				// Remove a callback from the list
3298				remove: function() {
3299					jQuery.each( arguments, function( _, arg ) {
3300						var index;
3301						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3302							list.splice( index, 1 );
3303
3304							// Handle firing indexes
3305							if ( index <= firingIndex ) {
3306								firingIndex--;
3307							}
3308						}
3309					} );
3310					return this;
3311				},
3312
3313				// Check if a given callback is in the list.
3314				// If no argument is given, return whether or not list has callbacks attached.
3315				has: function( fn ) {
3316					return fn ?
3317						jQuery.inArray( fn, list ) > -1 :
3318						list.length > 0;
3319				},
3320
3321				// Remove all callbacks from the list
3322				empty: function() {
3323					if ( list ) {
3324						list = [];
3325					}
3326					return this;
3327				},
3328
3329				// Disable .fire and .add
3330				// Abort any current/pending executions
3331				// Clear all callbacks and values
3332				disable: function() {
3333					locked = queue = [];
3334					list = memory = "";
3335					return this;
3336				},
3337				disabled: function() {
3338					return !list;
3339				},
3340
3341				// Disable .fire
3342				// Also disable .add unless we have memory (since it would have no effect)
3343				// Abort any pending executions
3344				lock: function() {
3345					locked = true;
3346					if ( !memory ) {
3347						self.disable();
3348					}
3349					return this;
3350				},
3351				locked: function() {
3352					return !!locked;
3353				},
3354
3355				// Call all callbacks with the given context and arguments
3356				fireWith: function( context, args ) {
3357					if ( !locked ) {
3358						args = args || [];
3359						args = [ context, args.slice ? args.slice() : args ];
3360						queue.push( args );
3361						if ( !firing ) {
3362							fire();
3363						}
3364					}
3365					return this;
3366				},
3367
3368				// Call all the callbacks with the given arguments
3369				fire: function() {
3370					self.fireWith( this, arguments );
3371					return this;
3372				},
3373
3374				// To know if the callbacks have already been called at least once
3375				fired: function() {
3376					return !!fired;
3377				}
3378			};
3379
3380		return self;
3381	};
3382
3383
3384	jQuery.extend( {
3385
3386		Deferred: function( func ) {
3387			var tuples = [
3388
3389					// action, add listener, listener list, final state
3390					[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3391					[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3392					[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3393				],
3394				state = "pending",
3395				promise = {
3396					state: function() {
3397						return state;
3398					},
3399					always: function() {
3400						deferred.done( arguments ).fail( arguments );
3401						return this;
3402					},
3403					then: function( /* fnDone, fnFail, fnProgress */ ) {
3404						var fns = arguments;
3405						return jQuery.Deferred( function( newDefer ) {
3406							jQuery.each( tuples, function( i, tuple ) {
3407								var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3408
3409								// deferred[ done | fail | progress ] for forwarding actions to newDefer
3410								deferred[ tuple[ 1 ] ]( function() {
3411									var returned = fn && fn.apply( this, arguments );
3412									if ( returned && jQuery.isFunction( returned.promise ) ) {
3413										returned.promise()
3414											.progress( newDefer.notify )
3415											.done( newDefer.resolve )
3416											.fail( newDefer.reject );
3417									} else {
3418										newDefer[ tuple[ 0 ] + "With" ](
3419											this === promise ? newDefer.promise() : this,
3420											fn ? [ returned ] : arguments
3421										);
3422									}
3423								} );
3424							} );
3425							fns = null;
3426						} ).promise();
3427					},
3428
3429					// Get a promise for this deferred
3430					// If obj is provided, the promise aspect is added to the object
3431					promise: function( obj ) {
3432						return obj != null ? jQuery.extend( obj, promise ) : promise;
3433					}
3434				},
3435				deferred = {};
3436
3437			// Keep pipe for back-compat
3438			promise.pipe = promise.then;
3439
3440			// Add list-specific methods
3441			jQuery.each( tuples, function( i, tuple ) {
3442				var list = tuple[ 2 ],
3443					stateString = tuple[ 3 ];
3444
3445				// promise[ done | fail | progress ] = list.add
3446				promise[ tuple[ 1 ] ] = list.add;
3447
3448				// Handle state
3449				if ( stateString ) {
3450					list.add( function() {
3451
3452						// state = [ resolved | rejected ]
3453						state = stateString;
3454
3455						// [ reject_list | resolve_list ].disable; progress_list.lock
3456					}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3457				}
3458
3459				// deferred[ resolve | reject | notify ]
3460				deferred[ tuple[ 0 ] ] = function() {
3461					deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3462					return this;
3463				};
3464				deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3465			} );
3466
3467			// Make the deferred a promise
3468			promise.promise( deferred );
3469
3470			// Call given func if any
3471			if ( func ) {
3472				func.call( deferred, deferred );
3473			}
3474
3475			// All done!
3476			return deferred;
3477		},
3478
3479		// Deferred helper
3480		when: function( subordinate /* , ..., subordinateN */ ) {
3481			var i = 0,
3482				resolveValues = slice.call( arguments ),
3483				length = resolveValues.length,
3484
3485				// the count of uncompleted subordinates
3486				remaining = length !== 1 ||
3487				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3488
3489				// the master Deferred.
3490				// If resolveValues consist of only a single Deferred, just use that.
3491				deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3492
3493				// Update function for both resolve and progress values
3494				updateFunc = function( i, contexts, values ) {
3495					return function( value ) {
3496						contexts[ i ] = this;
3497						values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3498						if ( values === progressValues ) {
3499							deferred.notifyWith( contexts, values );
3500
3501						} else if ( !( --remaining ) ) {
3502							deferred.resolveWith( contexts, values );
3503						}
3504					};
3505				},
3506
3507				progressValues, progressContexts, resolveContexts;
3508
3509			// add listeners to Deferred subordinates; treat others as resolved
3510			if ( length > 1 ) {
3511				progressValues = new Array( length );
3512				progressContexts = new Array( length );
3513				resolveContexts = new Array( length );
3514				for ( ; i < length; i++ ) {
3515					if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3516						resolveValues[ i ].promise()
3517							.progress( updateFunc( i, progressContexts, progressValues ) )
3518							.done( updateFunc( i, resolveContexts, resolveValues ) )
3519							.fail( deferred.reject );
3520					} else {
3521						--remaining;
3522					}
3523				}
3524			}
3525
3526			// if we're not waiting on anything, resolve the master
3527			if ( !remaining ) {
3528				deferred.resolveWith( resolveContexts, resolveValues );
3529			}
3530
3531			return deferred.promise();
3532		}
3533	} );
3534
3535
3536// The deferred used on DOM ready
3537	var readyList;
3538
3539	jQuery.fn.ready = function( fn ) {
3540
3541		// Add the callback
3542		jQuery.ready.promise().done( fn );
3543
3544		return this;
3545	};
3546
3547	jQuery.extend( {
3548
3549		// Is the DOM ready to be used? Set to true once it occurs.
3550		isReady: false,
3551
3552		// A counter to track how many items to wait for before
3553		// the ready event fires. See #6781
3554		readyWait: 1,
3555
3556		// Hold (or release) the ready event
3557		holdReady: function( hold ) {
3558			if ( hold ) {
3559				jQuery.readyWait++;
3560			} else {
3561				jQuery.ready( true );
3562			}
3563		},
3564
3565		// Handle when the DOM is ready
3566		ready: function( wait ) {
3567
3568			// Abort if there are pending holds or we're already ready
3569			if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3570				return;
3571			}
3572
3573			// Remember that the DOM is ready
3574			jQuery.isReady = true;
3575
3576			// If a normal DOM Ready event fired, decrement, and wait if need be
3577			if ( wait !== true && --jQuery.readyWait > 0 ) {
3578				return;
3579			}
3580
3581			// If there are functions bound, to execute
3582			readyList.resolveWith( document, [ jQuery ] );
3583
3584			// Trigger any bound ready events
3585			if ( jQuery.fn.triggerHandler ) {
3586				jQuery( document ).triggerHandler( "ready" );
3587				jQuery( document ).off( "ready" );
3588			}
3589		}
3590	} );
3591
3592	/**
3593	 * Clean-up method for dom ready events
3594	 */
3595	function detach() {
3596		if ( document.addEventListener ) {
3597			document.removeEventListener( "DOMContentLoaded", completed );
3598			window.removeEventListener( "load", completed );
3599
3600		} else {
3601			document.detachEvent( "onreadystatechange", completed );
3602			window.detachEvent( "onload", completed );
3603		}
3604	}
3605
3606	/**
3607	 * The ready event handler and self cleanup method
3608	 */
3609	function completed() {
3610
3611		// readyState === "complete" is good enough for us to call the dom ready in oldIE
3612		if ( document.addEventListener ||
3613			window.event.type === "load" ||
3614			document.readyState === "complete" ) {
3615
3616			detach();
3617			jQuery.ready();
3618		}
3619	}
3620
3621	jQuery.ready.promise = function( obj ) {
3622		if ( !readyList ) {
3623
3624			readyList = jQuery.Deferred();
3625
3626			// Catch cases where $(document).ready() is called
3627			// after the browser event has already occurred.
3628			// Support: IE6-10
3629			// Older IE sometimes signals "interactive" too soon
3630			if ( document.readyState === "complete" ||
3631				( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3632
3633				// Handle it asynchronously to allow scripts the opportunity to delay ready
3634				window.setTimeout( jQuery.ready );
3635
3636				// Standards-based browsers support DOMContentLoaded
3637			} else if ( document.addEventListener ) {
3638
3639				// Use the handy event callback
3640				document.addEventListener( "DOMContentLoaded", completed );
3641
3642				// A fallback to window.onload, that will always work
3643				window.addEventListener( "load", completed );
3644
3645				// If IE event model is used
3646			} else {
3647
3648				// Ensure firing before onload, maybe late but safe also for iframes
3649				document.attachEvent( "onreadystatechange", completed );
3650
3651				// A fallback to window.onload, that will always work
3652				window.attachEvent( "onload", completed );
3653
3654				// If IE and not a frame
3655				// continually check to see if the document is ready
3656				var top = false;
3657
3658				try {
3659					top = window.frameElement == null && document.documentElement;
3660				} catch ( e ) {}
3661
3662				if ( top && top.doScroll ) {
3663					( function doScrollCheck() {
3664						if ( !jQuery.isReady ) {
3665
3666							try {
3667
3668								// Use the trick by Diego Perini
3669								// http://javascript.nwbox.com/IEContentLoaded/
3670								top.doScroll( "left" );
3671							} catch ( e ) {
3672								return window.setTimeout( doScrollCheck, 50 );
3673							}
3674
3675							// detach all dom ready events
3676							detach();
3677
3678							// and execute any waiting functions
3679							jQuery.ready();
3680						}
3681					} )();
3682				}
3683			}
3684		}
3685		return readyList.promise( obj );
3686	};
3687
3688// Kick off the DOM ready check even if the user does not
3689	jQuery.ready.promise();
3690
3691
3692
3693
3694// Support: IE<9
3695// Iteration over object's inherited properties before its own
3696	var i;
3697	for ( i in jQuery( support ) ) {
3698		break;
3699	}
3700	support.ownFirst = i === "0";
3701
3702// Note: most support tests are defined in their respective modules.
3703// false until the test is run
3704	support.inlineBlockNeedsLayout = false;
vendor: 13,917 bytes, lines 3705-4256
3705
3706// Execute ASAP in case we need to set body.style.zoom
3707	jQuery( function() {
3708
3709		// Minified: var a,b,c,d
3710		var val, div, body, container;
3711
3712		body = document.getElementsByTagName( "body" )[ 0 ];
3713		if ( !body || !body.style ) {
3714
3715			// Return for frameset docs that don't have a body
3716			return;
3717		}
3718
3719		// Setup
3720		div = document.createElement( "div" );
3721		container = document.createElement( "div" );
3722		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3723		body.appendChild( container ).appendChild( div );
3724
3725		if ( typeof div.style.zoom !== "undefined" ) {
3726
3727			// Support: IE<8
3728			// Check if natively block-level elements act like inline-block
3729			// elements when setting their display to 'inline' and giving
3730			// them layout
3731			div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3732
3733			support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3734			if ( val ) {
3735
3736				// Prevent IE 6 from affecting layout for positioned elements #11048
3737				// Prevent IE from shrinking the body in IE 7 mode #12869
3738				// Support: IE<8
3739				body.style.zoom = 1;
3740			}
3741		}
3742
3743		body.removeChild( container );
3744	} );
3745
3746
3747	( function() {
3748		var div = document.createElement( "div" );
3749
3750		// Support: IE<9
3751		support.deleteExpando = true;
3752		try {
3753			delete div.test;
3754		} catch ( e ) {
3755			support.deleteExpando = false;
3756		}
3757
3758		// Null elements to avoid leaks in IE.
3759		div = null;
3760	} )();
3761	var acceptData = function( elem ) {
3762		var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
3763			nodeType = +elem.nodeType || 1;
3764
3765		// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3766		return nodeType !== 1 && nodeType !== 9 ?
3767			false :
3768
3769			// Nodes accept data unless otherwise specified; rejection can be conditional
3770			!noData || noData !== true && elem.getAttribute( "classid" ) === noData;
3771	};
3772
3773
3774
3775
3776	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3777		rmultiDash = /([A-Z])/g;
3778
3779	function dataAttr( elem, key, data ) {
3780
3781		// If nothing was found internally, try to fetch any
3782		// data from the HTML5 data-* attribute
3783		if ( data === undefined && elem.nodeType === 1 ) {
3784
3785			var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3786
3787			data = elem.getAttribute( name );
3788
3789			if ( typeof data === "string" ) {
3790				try {
3791					data = data === "true" ? true :
3792						data === "false" ? false :
3793							data === "null" ? null :
3794
3795								// Only convert to a number if it doesn't change the string
3796								+data + "" === data ? +data :
3797									rbrace.test( data ) ? jQuery.parseJSON( data ) :
3798										data;
3799				} catch ( e ) {}
3800
3801				// Make sure we set the data so it isn't changed later
3802				jQuery.data( elem, key, data );
3803
3804			} else {
3805				data = undefined;
3806			}
3807		}
3808
3809		return data;
3810	}
3811
3812// checks a cache object for emptiness
3813	function isEmptyDataObject( obj ) {
3814		var name;
3815		for ( name in obj ) {
3816
3817			// if the public data object is empty, the private is still empty
3818			if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
3819				continue;
3820			}
3821			if ( name !== "toJSON" ) {
3822				return false;
3823			}
3824		}
3825
3826		return true;
3827	}
3828
3829	function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3830		if ( !acceptData( elem ) ) {
3831			return;
3832		}
3833
3834		var ret, thisCache,
3835			internalKey = jQuery.expando,
3836
3837			// We have to handle DOM nodes and JS objects differently because IE6-7
3838			// can't GC object references properly across the DOM-JS boundary
3839			isNode = elem.nodeType,
3840
3841			// Only DOM nodes need the global jQuery cache; JS object data is
3842			// attached directly to the object so GC can occur automatically
3843			cache = isNode ? jQuery.cache : elem,
3844
3845			// Only defining an ID for JS objects if its cache already exists allows
3846			// the code to shortcut on the same path as a DOM node with no cache
3847			id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3848
3849		// Avoid doing any more work than we need to when trying to get data on an
3850		// object that has no data at all
3851		if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
3852			data === undefined && typeof name === "string" ) {
3853			return;
3854		}
3855
3856		if ( !id ) {
3857
3858			// Only DOM nodes need a new unique ID for each element since their data
3859			// ends up in the global cache
3860			if ( isNode ) {
3861				id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3862			} else {
3863				id = internalKey;
3864			}
3865		}
3866
3867		if ( !cache[ id ] ) {
3868
3869			// Avoid exposing jQuery metadata on plain JS objects when the object
3870			// is serialized using JSON.stringify
3871			cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3872		}
3873
3874		// An object can be passed to jQuery.data instead of a key/value pair; this gets
3875		// shallow copied over onto the existing cache
3876		if ( typeof name === "object" || typeof name === "function" ) {
3877			if ( pvt ) {
3878				cache[ id ] = jQuery.extend( cache[ id ], name );
3879			} else {
3880				cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3881			}
3882		}
3883
3884		thisCache = cache[ id ];
3885
3886		// jQuery data() is stored in a separate object inside the object's internal data
3887		// cache in order to avoid key collisions between internal data and user-defined
3888		// data.
3889		if ( !pvt ) {
3890			if ( !thisCache.data ) {
3891				thisCache.data = {};
3892			}
3893
3894			thisCache = thisCache.data;
3895		}
3896
3897		if ( data !== undefined ) {
3898			thisCache[ jQuery.camelCase( name ) ] = data;
3899		}
3900
3901		// Check for both converted-to-camel and non-converted data property names
3902		// If a data property was specified
3903		if ( typeof name === "string" ) {
3904
3905			// First Try to find as-is property data
3906			ret = thisCache[ name ];
3907
3908			// Test for null|undefined property data
3909			if ( ret == null ) {
3910
3911				// Try to find the camelCased property
3912				ret = thisCache[ jQuery.camelCase( name ) ];
3913			}
3914		} else {
3915			ret = thisCache;
3916		}
3917
3918		return ret;
3919	}
3920
3921	function internalRemoveData( elem, name, pvt ) {
3922		if ( !acceptData( elem ) ) {
3923			return;
3924		}
3925
3926		var thisCache, i,
3927			isNode = elem.nodeType,
3928
3929			// See jQuery.data for more information
3930			cache = isNode ? jQuery.cache : elem,
3931			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3932
3933		// If there is already no cache entry for this object, there is no
3934		// purpose in continuing
3935		if ( !cache[ id ] ) {
3936			return;
3937		}
3938
3939		if ( name ) {
3940
3941			thisCache = pvt ? cache[ id ] : cache[ id ].data;
3942
3943			if ( thisCache ) {
3944
3945				// Support array or space separated string names for data keys
3946				if ( !jQuery.isArray( name ) ) {
3947
3948					// try the string as a key before any manipulation
3949					if ( name in thisCache ) {
3950						name = [ name ];
3951					} else {
3952
3953						// split the camel cased version by spaces unless a key with the spaces exists
3954						name = jQuery.camelCase( name );
3955						if ( name in thisCache ) {
3956							name = [ name ];
3957						} else {
3958							name = name.split( " " );
3959						}
3960					}
3961				} else {
3962
3963					// If "name" is an array of keys...
3964					// When data is initially created, via ("key", "val") signature,
3965					// keys will be converted to camelCase.
3966					// Since there is no way to tell _how_ a key was added, remove
3967					// both plain key and camelCase key. #12786
3968					// This will only penalize the array argument path.
3969					name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3970				}
3971
3972				i = name.length;
3973				while ( i-- ) {
3974					delete thisCache[ name[ i ] ];
3975				}
3976
3977				// If there is no data left in the cache, we want to continue
3978				// and let the cache object itself get destroyed
3979				if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
3980					return;
3981				}
3982			}
3983		}
3984
3985		// See jQuery.data for more information
3986		if ( !pvt ) {
3987			delete cache[ id ].data;
3988
3989			// Don't destroy the parent cache unless the internal data object
3990			// had been the only thing left in it
3991			if ( !isEmptyDataObject( cache[ id ] ) ) {
3992				return;
3993			}
3994		}
3995
3996		// Destroy the cache
3997		if ( isNode ) {
3998			jQuery.cleanData( [ elem ], true );
3999
4000			// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
4001			/* jshint eqeqeq: false */
4002		} else if ( support.deleteExpando || cache != cache.window ) {
4003			/* jshint eqeqeq: true */
4004			delete cache[ id ];
4005
4006			// When all else fails, undefined
4007		} else {
4008			cache[ id ] = undefined;
4009		}
4010	}
4011
4012	jQuery.extend( {
4013		cache: {},
4014
4015		// The following elements (space-suffixed to avoid Object.prototype collisions)
4016		// throw uncatchable exceptions if you attempt to set expando properties
4017		noData: {
4018			"applet ": true,
4019			"embed ": true,
4020
4021			// ...but Flash objects (which have this classid) *can* handle expandos
4022			"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
4023		},
4024
4025		hasData: function( elem ) {
4026			elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
4027			return !!elem && !isEmptyDataObject( elem );
4028		},
4029
4030		data: function( elem, name, data ) {
4031			return internalData( elem, name, data );
4032		},
4033
4034		removeData: function( elem, name ) {
4035			return internalRemoveData( elem, name );
4036		},
4037
4038		// For internal use only.
4039		_data: function( elem, name, data ) {
4040			return internalData( elem, name, data, true );
4041		},
4042
4043		_removeData: function( elem, name ) {
4044			return internalRemoveData( elem, name, true );
4045		}
4046	} );
4047
4048	jQuery.fn.extend( {
4049		data: function( key, value ) {
4050			var i, name, data,
4051				elem = this[ 0 ],
4052				attrs = elem && elem.attributes;
4053
4054			// Special expections of .data basically thwart jQuery.access,
4055			// so implement the relevant behavior ourselves
4056
4057			// Gets all values
4058			if ( key === undefined ) {
4059				if ( this.length ) {
4060					data = jQuery.data( elem );
4061
4062					if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
4063						i = attrs.length;
4064						while ( i-- ) {
4065
4066							// Support: IE11+
4067							// The attrs elements can be null (#14894)
4068							if ( attrs[ i ] ) {
4069								name = attrs[ i ].name;
4070								if ( name.indexOf( "data-" ) === 0 ) {
4071									name = jQuery.camelCase( name.slice( 5 ) );
4072									dataAttr( elem, name, data[ name ] );
4073								}
4074							}
4075						}
4076						jQuery._data( elem, "parsedAttrs", true );
4077					}
4078				}
4079
4080				return data;
4081			}
4082
4083			// Sets multiple values
4084			if ( typeof key === "object" ) {
4085				return this.each( function() {
4086					jQuery.data( this, key );
4087				} );
4088			}
4089
4090			return arguments.length > 1 ?
4091
4092				// Sets one value
4093				this.each( function() {
4094					jQuery.data( this, key, value );
4095				} ) :
4096
4097				// Gets one value
4098				// Try to fetch any internally stored data first
4099				elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
4100		},
4101
4102		removeData: function( key ) {
4103			return this.each( function() {
4104				jQuery.removeData( this, key );
4105			} );
4106		}
4107	} );
4108
4109
4110	jQuery.extend( {
4111		queue: function( elem, type, data ) {
4112			var queue;
4113
4114			if ( elem ) {
4115				type = ( type || "fx" ) + "queue";
4116				queue = jQuery._data( elem, type );
4117
4118				// Speed up dequeue by getting out quickly if this is just a lookup
4119				if ( data ) {
4120					if ( !queue || jQuery.isArray( data ) ) {
4121						queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
4122					} else {
4123						queue.push( data );
4124					}
4125				}
4126				return queue || [];
4127			}
4128		},
4129
4130		dequeue: function( elem, type ) {
4131			type = type || "fx";
4132
4133			var queue = jQuery.queue( elem, type ),
4134				startLength = queue.length,
4135				fn = queue.shift(),
4136				hooks = jQuery._queueHooks( elem, type ),
4137				next = function() {
4138					jQuery.dequeue( elem, type );
4139				};
4140
4141			// If the fx queue is dequeued, always remove the progress sentinel
4142			if ( fn === "inprogress" ) {
4143				fn = queue.shift();
4144				startLength--;
4145			}
4146
4147			if ( fn ) {
4148
4149				// Add a progress sentinel to prevent the fx queue from being
4150				// automatically dequeued
4151				if ( type === "fx" ) {
4152					queue.unshift( "inprogress" );
4153				}
4154
4155				// clear up the last queue stop function
4156				delete hooks.stop;
4157				fn.call( elem, next, hooks );
4158			}
4159
4160			if ( !startLength && hooks ) {
4161				hooks.empty.fire();
4162			}
4163		},
4164
4165		// not intended for public consumption - generates a queueHooks object,
4166		// or returns the current one
4167		_queueHooks: function( elem, type ) {
4168			var key = type + "queueHooks";
4169			return jQuery._data( elem, key ) || jQuery._data( elem, key, {
4170				empty: jQuery.Callbacks( "once memory" ).add( function() {
4171					jQuery._removeData( elem, type + "queue" );
4172					jQuery._removeData( elem, key );
4173				} )
4174			} );
4175		}
4176	} );
4177
4178	jQuery.fn.extend( {
4179		queue: function( type, data ) {
4180			var setter = 2;
4181
4182			if ( typeof type !== "string" ) {
4183				data = type;
4184				type = "fx";
4185				setter--;
4186			}
4187
4188			if ( arguments.length < setter ) {
4189				return jQuery.queue( this[ 0 ], type );
4190			}
4191
4192			return data === undefined ?
4193				this :
4194				this.each( function() {
4195					var queue = jQuery.queue( this, type, data );
4196
4197					// ensure a hooks for this queue
4198					jQuery._queueHooks( this, type );
4199
4200					if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4201						jQuery.dequeue( this, type );
4202					}
4203				} );
4204		},
4205		dequeue: function( type ) {
4206			return this.each( function() {
4207				jQuery.dequeue( this, type );
4208			} );
4209		},
4210		clearQueue: function( type ) {
4211			return this.queue( type || "fx", [] );
4212		},
4213
4214		// Get a promise resolved when queues of a certain type
4215		// are emptied (fx is the type by default)
4216		promise: function( type, obj ) {
4217			var tmp,
4218				count = 1,
4219				defer = jQuery.Deferred(),
4220				elements = this,
4221				i = this.length,
4222				resolve = function() {
4223					if ( !( --count ) ) {
4224						defer.resolveWith( elements, [ elements ] );
4225					}
4226				};
4227
4228			if ( typeof type !== "string" ) {
4229				obj = type;
4230				type = undefined;
4231			}
4232			type = type || "fx";
4233
4234			while ( i-- ) {
4235				tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4236				if ( tmp && tmp.empty ) {
4237					count++;
4238					tmp.empty.add( resolve );
4239				}
4240			}
4241			resolve();
4242			return defer.promise( obj );
4243		}
4244	} );
4245
4246
4247	( function() {
4248		var shrinkWrapBlocksVal;
4249
4250		support.shrinkWrapBlocks = function() {
4251			if ( shrinkWrapBlocksVal != null ) {
4252				return shrinkWrapBlocksVal;
4253			}
4254
4255			// Will be changed later if needed.
4256			shrinkWrapBlocksVal = false;
vendor: 4,280 bytes, lines 4257-4405
4257
4258			// Minified: var b,c,d
4259			var div, body, container;
4260
4261			body = document.getElementsByTagName( "body" )[ 0 ];
4262			if ( !body || !body.style ) {
4263
4264				// Test fired too early or in an unsupported environment, exit.
4265				return;
4266			}
4267
4268			// Setup
4269			div = document.createElement( "div" );
4270			container = document.createElement( "div" );
4271			container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
4272			body.appendChild( container ).appendChild( div );
4273
4274			// Support: IE6
4275			// Check if elements with layout shrink-wrap their children
4276			if ( typeof div.style.zoom !== "undefined" ) {
4277
4278				// Reset CSS: box-sizing; display; margin; border
4279				div.style.cssText =
4280
4281					// Support: Firefox<29, Android 2.3
4282					// Vendor-prefix box-sizing
4283					"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
4284					"box-sizing:content-box;display:block;margin:0;border:0;" +
4285					"padding:1px;width:1px;zoom:1";
4286				div.appendChild( document.createElement( "div" ) ).style.width = "5px";
4287				shrinkWrapBlocksVal = div.offsetWidth !== 3;
4288			}
4289
4290			body.removeChild( container );
4291
4292			return shrinkWrapBlocksVal;
4293		};
4294
4295	} )();
4296	var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4297
4298	var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4299
4300
4301	var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4302
4303	var isHidden = function( elem, el ) {
4304
4305		// isHidden might be called from jQuery#filter function;
4306		// in that case, element will be second argument
4307		elem = el || elem;
4308		return jQuery.css( elem, "display" ) === "none" ||
4309			!jQuery.contains( elem.ownerDocument, elem );
4310	};
4311
4312
4313
4314	function adjustCSS( elem, prop, valueParts, tween ) {
4315		var adjusted,
4316			scale = 1,
4317			maxIterations = 20,
4318			currentValue = tween ?
4319				function() { return tween.cur(); } :
4320				function() { return jQuery.css( elem, prop, "" ); },
4321			initial = currentValue(),
4322			unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4323
4324			// Starting value computation is required for potential unit mismatches
4325			initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4326				rcssNum.exec( jQuery.css( elem, prop ) );
4327
4328		if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4329
4330			// Trust units reported by jQuery.css
4331			unit = unit || initialInUnit[ 3 ];
4332
4333			// Make sure we update the tween properties later on
4334			valueParts = valueParts || [];
4335
4336			// Iteratively approximate from a nonzero starting point
4337			initialInUnit = +initial || 1;
4338
4339			do {
4340
4341				// If previous iteration zeroed out, double until we get *something*.
4342				// Use string for doubling so we don't accidentally see scale as unchanged below
4343				scale = scale || ".5";
4344
4345				// Adjust and apply
4346				initialInUnit = initialInUnit / scale;
4347				jQuery.style( elem, prop, initialInUnit + unit );
4348
4349				// Update scale, tolerating zero or NaN from tween.cur()
4350				// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4351			} while (
4352				scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4353				);
4354		}
4355
4356		if ( valueParts ) {
4357			initialInUnit = +initialInUnit || +initial || 0;
4358
4359			// Apply relative offset (+=/-=) if specified
4360			adjusted = valueParts[ 1 ] ?
4361				initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4362				+valueParts[ 2 ];
4363			if ( tween ) {
4364				tween.unit = unit;
4365				tween.start = initialInUnit;
4366				tween.end = adjusted;
4367			}
4368		}
4369		return adjusted;
4370	}
4371
4372
4373// Multifunctional method to get and set values of a collection
4374// The value/s can optionally be executed if it's a function
4375	var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4376		var i = 0,
4377			length = elems.length,
4378			bulk = key == null;
4379
4380		// Sets many values
4381		if ( jQuery.type( key ) === "object" ) {
4382			chainable = true;
4383			for ( i in key ) {
4384				access( elems, fn, i, key[ i ], true, emptyGet, raw );
4385			}
4386
4387			// Sets one value
4388		} else if ( value !== undefined ) {
4389			chainable = true;
4390
4391			if ( !jQuery.isFunction( value ) ) {
4392				raw = true;
4393			}
4394
4395			if ( bulk ) {
4396
4397				// Bulk operations run against the entire set
4398				if ( raw ) {
4399					fn.call( elems, value );
4400					fn = null;
4401
4402					// ...except when executing function values
4403				} else {
4404					bulk = fn;
4405					fn = function( elem, key, value ) {
4406						return bulk.call( jQuery( elem ), value );
4407					};
4408				}
4409			}
4410
4411			if ( fn ) {
4412				for ( ; i < length; i++ ) {
4413					fn(
4414						elems[ i ],
4415						key,
4416						raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
4417					);
4418				}
4419			}
4420		}
4421
4422		return chainable ?
4423			elems :
4424
4425			// Gets
4426			bulk ?
4427				fn.call( elems ) :
4428				length ? fn( elems[ 0 ], key ) : emptyGet;
4429	};
4430	var rcheckableType = ( /^(?:checkbox|radio)$/i );
4431
4432	var rtagName = ( /<([\w:-]+)/ );
4433
4434	var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4435
4436	var rleadingWhitespace = ( /^\s+/ );
4437
4438	var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
4439		"details|dialog|figcaption|figure|footer|header|hgroup|main|" +
4440		"mark|meter|nav|output|picture|progress|section|summary|template|time|video";
4441
4442
4443
4444	function createSafeFragment( document ) {
4445		var list = nodeNames.split( "|" ),
4446			safeFrag = document.createDocumentFragment();
4447
4448		if ( safeFrag.createElement ) {
4449			while ( list.length ) {
4450				safeFrag.createElement(
4451					list.pop()
4452				);
4453			}
4454		}
4455		return safeFrag;
4456	}
4457
4458
4459	( function() {
4460		var div = document.createElement( "div" ),
4461			fragment = document.createDocumentFragment(),
4462			input = document.createElement( "input" );
4463
4464		// Setup
4465		div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4466
4467		// IE strips leading whitespace when .innerHTML is used
4468		support.leadingWhitespace = div.firstChild.nodeType === 3;
4469
4470		// Make sure that tbody elements aren't automatically inserted
4471		// IE will insert them into empty tables
4472		support.tbody = !div.getElementsByTagName( "tbody" ).length;
4473
4474		// Make sure that link elements get serialized correctly by innerHTML
4475		// This requires a wrapper element in IE
4476		support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4477
4478		// Makes sure cloning an html5 element does not cause problems
4479		// Where outerHTML is undefined, this still works
4480		support.html5Clone =
4481			document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4482
4483		// Check if a disconnected checkbox will retain its checked
4484		// value of true after appended to the DOM (IE6/7)
4485		input.type = "checkbox";
4486		input.checked = true;
4487		fragment.appendChild( input );
4488		support.appendChecked = input.checked;
4489
4490		// Make sure textarea (and checkbox) defaultValue is properly cloned
4491		// Support: IE6-IE11+
4492		div.innerHTML = "<textarea>x</textarea>";
4493		support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4494
4495		// #11217 - WebKit loses check when the name is after the checked attribute
4496		fragment.appendChild( div );
4497
4498		// Support: Windows Web Apps (WWA)
4499		// `name` and `type` must use .setAttribute for WWA (#14901)
4500		input = document.createElement( "input" );
4501		input.setAttribute( "type", "radio" );
4502		input.setAttribute( "checked", "checked" );
4503		input.setAttribute( "name", "t" );
4504
4505		div.appendChild( input );
4506
4507		// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4508		// old WebKit doesn't clone checked state correctly in fragments
4509		support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4510
4511		// Support: IE<9
4512		// Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
4513		support.noCloneEvent = !!div.addEventListener;
4514
4515		// Support: IE<9
4516		// Since attributes and properties are the same in IE,
4517		// cleanData must set properties to undefined rather than use removeAttribute
4518		div[ jQuery.expando ] = 1;
4519		support.attributes = !div.getAttribute( jQuery.expando );
4520	} )();
4521
4522
4523// We have to close these tags to support XHTML (#13200)
4524	var wrapMap = {
4525		option: [ 1, "<select multiple='multiple'>", "</select>" ],
4526		legend: [ 1, "<fieldset>", "</fieldset>" ],
4527		area: [ 1, "<map>", "</map>" ],
4528
4529		// Support: IE8
4530		param: [ 1, "<object>", "</object>" ],
4531		thead: [ 1, "<table>", "</table>" ],
4532		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4533		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4534		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4535
4536		// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
4537		// unless wrapped in a div with non-breaking characters in front of it.
4538		_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
4539	};
4540
4541// Support: IE8-IE9
4542	wrapMap.optgroup = wrapMap.option;
4543
4544	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4545	wrapMap.th = wrapMap.td;
4546
4547
4548	function getAll( context, tag ) {
4549		var elems, elem,
4550			i = 0,
4551			found = typeof context.getElementsByTagName !== "undefined" ?
4552				context.getElementsByTagName( tag || "*" ) :
4553				typeof context.querySelectorAll !== "undefined" ?
4554					context.querySelectorAll( tag || "*" ) :
4555					undefined;
4556
4557		if ( !found ) {
4558			for ( found = [], elems = context.childNodes || context;
4559				  ( elem = elems[ i ] ) != null;
4560				  i++
4561			) {
4562				if ( !tag || jQuery.nodeName( elem, tag ) ) {
4563					found.push( elem );
4564				} else {
4565					jQuery.merge( found, getAll( elem, tag ) );
4566				}
4567			}
4568		}
4569
4570		return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4571			jQuery.merge( [ context ], found ) :
4572			found;
4573	}
4574
4575
4576// Mark scripts as having already been evaluated
4577	function setGlobalEval( elems, refElements ) {
4578		var elem,
4579			i = 0;
4580		for ( ; ( elem = elems[ i ] ) != null; i++ ) {
4581			jQuery._data(
4582				elem,
4583				"globalEval",
4584				!refElements || jQuery._data( refElements[ i ], "globalEval" )
4585			);
4586		}
4587	}
4588
4589
vendor: 46,841 bytes, lines 4590-6222
4590	var rhtml = /<|&#?\w+;/,
4591		rtbody = /<tbody/i;
4592
4593	function fixDefaultChecked( elem ) {
4594		if ( rcheckableType.test( elem.type ) ) {
4595			elem.defaultChecked = elem.checked;
4596		}
4597	}
4598
4599	function buildFragment( elems, context, scripts, selection, ignored ) {
4600		var j, elem, contains,
4601			tmp, tag, tbody, wrap,
4602			l = elems.length,
4603
4604			// Ensure a safe fragment
4605			safe = createSafeFragment( context ),
4606
4607			nodes = [],
4608			i = 0;
4609
4610		for ( ; i < l; i++ ) {
4611			elem = elems[ i ];
4612
4613			if ( elem || elem === 0 ) {
4614
4615				// Add nodes directly
4616				if ( jQuery.type( elem ) === "object" ) {
4617					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4618
4619					// Convert non-html into a text node
4620				} else if ( !rhtml.test( elem ) ) {
4621					nodes.push( context.createTextNode( elem ) );
4622
4623					// Convert html into DOM nodes
4624				} else {
4625					tmp = tmp || safe.appendChild( context.createElement( "div" ) );
4626
4627					// Deserialize a standard representation
4628					tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4629					wrap = wrapMap[ tag ] || wrapMap._default;
4630
4631					tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4632
4633					// Descend through wrappers to the right content
4634					j = wrap[ 0 ];
4635					while ( j-- ) {
4636						tmp = tmp.lastChild;
4637					}
4638
4639					// Manually add leading whitespace removed by IE
4640					if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4641						nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
4642					}
4643
4644					// Remove IE's autoinserted <tbody> from table fragments
4645					if ( !support.tbody ) {
4646
4647						// String was a <table>, *may* have spurious <tbody>
4648						elem = tag === "table" && !rtbody.test( elem ) ?
4649							tmp.firstChild :
4650
4651							// String was a bare <thead> or <tfoot>
4652							wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
4653								tmp :
4654								0;
4655
4656						j = elem && elem.childNodes.length;
4657						while ( j-- ) {
4658							if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
4659								!tbody.childNodes.length ) {
4660
4661								elem.removeChild( tbody );
4662							}
4663						}
4664					}
4665
4666					jQuery.merge( nodes, tmp.childNodes );
4667
4668					// Fix #12392 for WebKit and IE > 9
4669					tmp.textContent = "";
4670
4671					// Fix #12392 for oldIE
4672					while ( tmp.firstChild ) {
4673						tmp.removeChild( tmp.firstChild );
4674					}
4675
4676					// Remember the top-level container for proper cleanup
4677					tmp = safe.lastChild;
4678				}
4679			}
4680		}
4681
4682		// Fix #11356: Clear elements from fragment
4683		if ( tmp ) {
4684			safe.removeChild( tmp );
4685		}
4686
4687		// Reset defaultChecked for any radios and checkboxes
4688		// about to be appended to the DOM in IE 6/7 (#8060)
4689		if ( !support.appendChecked ) {
4690			jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
4691		}
4692
4693		i = 0;
4694		while ( ( elem = nodes[ i++ ] ) ) {
4695
4696			// Skip elements already in the context collection (trac-4087)
4697			if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4698				if ( ignored ) {
4699					ignored.push( elem );
4700				}
4701
4702				continue;
4703			}
4704
4705			contains = jQuery.contains( elem.ownerDocument, elem );
4706
4707			// Append to fragment
4708			tmp = getAll( safe.appendChild( elem ), "script" );
4709
4710			// Preserve script evaluation history
4711			if ( contains ) {
4712				setGlobalEval( tmp );
4713			}
4714
4715			// Capture executables
4716			if ( scripts ) {
4717				j = 0;
4718				while ( ( elem = tmp[ j++ ] ) ) {
4719					if ( rscriptType.test( elem.type || "" ) ) {
4720						scripts.push( elem );
4721					}
4722				}
4723			}
4724		}
4725
4726		tmp = null;
4727
4728		return safe;
4729	}
4730
4731
4732	( function() {
4733		var i, eventName,
4734			div = document.createElement( "div" );
4735
4736		// Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
4737		for ( i in { submit: true, change: true, focusin: true } ) {
4738			eventName = "on" + i;
4739
4740			if ( !( support[ i ] = eventName in window ) ) {
4741
4742				// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4743				div.setAttribute( eventName, "t" );
4744				support[ i ] = div.attributes[ eventName ].expando === false;
4745			}
4746		}
4747
4748		// Null elements to avoid leaks in IE.
4749		div = null;
4750	} )();
4751
4752
4753	var rformElems = /^(?:input|select|textarea)$/i,
4754		rkeyEvent = /^key/,
4755		rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4756		rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4757		rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4758
4759	function returnTrue() {
4760		return true;
4761	}
4762
4763	function returnFalse() {
4764		return false;
4765	}
4766
4767// Support: IE9
4768// See #13393 for more info
4769	function safeActiveElement() {
4770		try {
4771			return document.activeElement;
4772		} catch ( err ) { }
4773	}
4774
4775	function on( elem, types, selector, data, fn, one ) {
4776		var origFn, type;
4777
4778		// Types can be a map of types/handlers
4779		if ( typeof types === "object" ) {
4780
4781			// ( types-Object, selector, data )
4782			if ( typeof selector !== "string" ) {
4783
4784				// ( types-Object, data )
4785				data = data || selector;
4786				selector = undefined;
4787			}
4788			for ( type in types ) {
4789				on( elem, type, selector, data, types[ type ], one );
4790			}
4791			return elem;
4792		}
4793
4794		if ( data == null && fn == null ) {
4795
4796			// ( types, fn )
4797			fn = selector;
4798			data = selector = undefined;
4799		} else if ( fn == null ) {
4800			if ( typeof selector === "string" ) {
4801
4802				// ( types, selector, fn )
4803				fn = data;
4804				data = undefined;
4805			} else {
4806
4807				// ( types, data, fn )
4808				fn = data;
4809				data = selector;
4810				selector = undefined;
4811			}
4812		}
4813		if ( fn === false ) {
4814			fn = returnFalse;
4815		} else if ( !fn ) {
4816			return elem;
4817		}
4818
4819		if ( one === 1 ) {
4820			origFn = fn;
4821			fn = function( event ) {
4822
4823				// Can use an empty set, since event contains the info
4824				jQuery().off( event );
4825				return origFn.apply( this, arguments );
4826			};
4827
4828			// Use same guid so caller can remove using origFn
4829			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4830		}
4831		return elem.each( function() {
4832			jQuery.event.add( this, types, fn, data, selector );
4833		} );
4834	}
4835
4836	/*
4837 * Helper functions for managing events -- not part of the public interface.
4838 * Props to Dean Edwards' addEvent library for many of the ideas.
4839 */
4840	jQuery.event = {
4841
4842		global: {},
4843
4844		add: function( elem, types, handler, data, selector ) {
4845			var tmp, events, t, handleObjIn,
4846				special, eventHandle, handleObj,
4847				handlers, type, namespaces, origType,
4848				elemData = jQuery._data( elem );
4849
4850			// Don't attach events to noData or text/comment nodes (but allow plain objects)
4851			if ( !elemData ) {
4852				return;
4853			}
4854
4855			// Caller can pass in an object of custom data in lieu of the handler
4856			if ( handler.handler ) {
4857				handleObjIn = handler;
4858				handler = handleObjIn.handler;
4859				selector = handleObjIn.selector;
4860			}
4861
4862			// Make sure that the handler has a unique ID, used to find/remove it later
4863			if ( !handler.guid ) {
4864				handler.guid = jQuery.guid++;
4865			}
4866
4867			// Init the element's event structure and main handler, if this is the first
4868			if ( !( events = elemData.events ) ) {
4869				events = elemData.events = {};
4870			}
4871			if ( !( eventHandle = elemData.handle ) ) {
4872				eventHandle = elemData.handle = function( e ) {
4873
4874					// Discard the second event of a jQuery.event.trigger() and
4875					// when an event is called after a page has unloaded
4876					return typeof jQuery !== "undefined" &&
4877					( !e || jQuery.event.triggered !== e.type ) ?
4878						jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4879						undefined;
4880				};
4881
4882				// Add elem as a property of the handle fn to prevent a memory leak
4883				// with IE non-native events
4884				eventHandle.elem = elem;
4885			}
4886
4887			// Handle multiple events separated by a space
4888			types = ( types || "" ).match( rnotwhite ) || [ "" ];
4889			t = types.length;
4890			while ( t-- ) {
4891				tmp = rtypenamespace.exec( types[ t ] ) || [];
4892				type = origType = tmp[ 1 ];
4893				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4894
4895				// There *must* be a type, no attaching namespace-only handlers
4896				if ( !type ) {
4897					continue;
4898				}
4899
4900				// If event changes its type, use the special event handlers for the changed type
4901				special = jQuery.event.special[ type ] || {};
4902
4903				// If selector defined, determine special event api type, otherwise given type
4904				type = ( selector ? special.delegateType : special.bindType ) || type;
4905
4906				// Update special based on newly reset type
4907				special = jQuery.event.special[ type ] || {};
4908
4909				// handleObj is passed to all event handlers
4910				handleObj = jQuery.extend( {
4911					type: type,
4912					origType: origType,
4913					data: data,
4914					handler: handler,
4915					guid: handler.guid,
4916					selector: selector,
4917					needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4918					namespace: namespaces.join( "." )
4919				}, handleObjIn );
4920
4921				// Init the event handler queue if we're the first
4922				if ( !( handlers = events[ type ] ) ) {
4923					handlers = events[ type ] = [];
4924					handlers.delegateCount = 0;
4925
4926					// Only use addEventListener/attachEvent if the special events handler returns false
4927					if ( !special.setup ||
4928						special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4929
4930						// Bind the global event handler to the element
4931						if ( elem.addEventListener ) {
4932							elem.addEventListener( type, eventHandle, false );
4933
4934						} else if ( elem.attachEvent ) {
4935							elem.attachEvent( "on" + type, eventHandle );
4936						}
4937					}
4938				}
4939
4940				if ( special.add ) {
4941					special.add.call( elem, handleObj );
4942
4943					if ( !handleObj.handler.guid ) {
4944						handleObj.handler.guid = handler.guid;
4945					}
4946				}
4947
4948				// Add to the element's handler list, delegates in front
4949				if ( selector ) {
4950					handlers.splice( handlers.delegateCount++, 0, handleObj );
4951				} else {
4952					handlers.push( handleObj );
4953				}
4954
4955				// Keep track of which events have ever been used, for event optimization
4956				jQuery.event.global[ type ] = true;
4957			}
4958
4959			// Nullify elem to prevent memory leaks in IE
4960			elem = null;
4961		},
4962
4963		// Detach an event or set of events from an element
4964		remove: function( elem, types, handler, selector, mappedTypes ) {
4965			var j, handleObj, tmp,
4966				origCount, t, events,
4967				special, handlers, type,
4968				namespaces, origType,
4969				elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4970
4971			if ( !elemData || !( events = elemData.events ) ) {
4972				return;
4973			}
4974
4975			// Once for each type.namespace in types; type may be omitted
4976			types = ( types || "" ).match( rnotwhite ) || [ "" ];
4977			t = types.length;
4978			while ( t-- ) {
4979				tmp = rtypenamespace.exec( types[ t ] ) || [];
4980				type = origType = tmp[ 1 ];
4981				namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4982
4983				// Unbind all events (on this namespace, if provided) for the element
4984				if ( !type ) {
4985					for ( type in events ) {
4986						jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4987					}
4988					continue;
4989				}
4990
4991				special = jQuery.event.special[ type ] || {};
4992				type = ( selector ? special.delegateType : special.bindType ) || type;
4993				handlers = events[ type ] || [];
4994				tmp = tmp[ 2 ] &&
4995					new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4996
4997				// Remove matching events
4998				origCount = j = handlers.length;
4999				while ( j-- ) {
5000					handleObj = handlers[ j ];
5001
5002					if ( ( mappedTypes || origType === handleObj.origType ) &&
5003						( !handler || handler.guid === handleObj.guid ) &&
5004						( !tmp || tmp.test( handleObj.namespace ) ) &&
5005						( !selector || selector === handleObj.selector ||
5006							selector === "**" && handleObj.selector ) ) {
5007						handlers.splice( j, 1 );
5008
5009						if ( handleObj.selector ) {
5010							handlers.delegateCount--;
5011						}
5012						if ( special.remove ) {
5013							special.remove.call( elem, handleObj );
5014						}
5015					}
5016				}
5017
5018				// Remove generic event handler if we removed something and no more handlers exist
5019				// (avoids potential for endless recursion during removal of special event handlers)
5020				if ( origCount && !handlers.length ) {
5021					if ( !special.teardown ||
5022						special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5023
5024						jQuery.removeEvent( elem, type, elemData.handle );
5025					}
5026
5027					delete events[ type ];
5028				}
5029			}
5030
5031			// Remove the expando if it's no longer used
5032			if ( jQuery.isEmptyObject( events ) ) {
5033				delete elemData.handle;
5034
5035				// removeData also checks for emptiness and clears the expando if empty
5036				// so use it instead of delete
5037				jQuery._removeData( elem, "events" );
5038			}
5039		},
5040
5041		trigger: function( event, data, elem, onlyHandlers ) {
5042			var handle, ontype, cur,
5043				bubbleType, special, tmp, i,
5044				eventPath = [ elem || document ],
5045				type = hasOwn.call( event, "type" ) ? event.type : event,
5046				namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
5047
5048			cur = tmp = elem = elem || document;
5049
5050			// Don't do events on text and comment nodes
5051			if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
5052				return;
5053			}
5054
5055			// focus/blur morphs to focusin/out; ensure we're not firing them right now
5056			if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
5057				return;
5058			}
5059
5060			if ( type.indexOf( "." ) > -1 ) {
5061
5062				// Namespaced trigger; create a regexp to match event type in handle()
5063				namespaces = type.split( "." );
5064				type = namespaces.shift();
5065				namespaces.sort();
5066			}
5067			ontype = type.indexOf( ":" ) < 0 && "on" + type;
5068
5069			// Caller can pass in a jQuery.Event object, Object, or just an event type string
5070			event = event[ jQuery.expando ] ?
5071				event :
5072				new jQuery.Event( type, typeof event === "object" && event );
5073
5074			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
5075			event.isTrigger = onlyHandlers ? 2 : 3;
5076			event.namespace = namespaces.join( "." );
5077			event.rnamespace = event.namespace ?
5078				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
5079				null;
5080
5081			// Clean up the event in case it is being reused
5082			event.result = undefined;
5083			if ( !event.target ) {
5084				event.target = elem;
5085			}
5086
5087			// Clone any incoming data and prepend the event, creating the handler arg list
5088			data = data == null ?
5089				[ event ] :
5090				jQuery.makeArray( data, [ event ] );
5091
5092			// Allow special events to draw outside the lines
5093			special = jQuery.event.special[ type ] || {};
5094			if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
5095				return;
5096			}
5097
5098			// Determine event propagation path in advance, per W3C events spec (#9951)
5099			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
5100			if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
5101
5102				bubbleType = special.delegateType || type;
5103				if ( !rfocusMorph.test( bubbleType + type ) ) {
5104					cur = cur.parentNode;
5105				}
5106				for ( ; cur; cur = cur.parentNode ) {
5107					eventPath.push( cur );
5108					tmp = cur;
5109				}
5110
5111				// Only add window if we got to document (e.g., not plain obj or detached DOM)
5112				if ( tmp === ( elem.ownerDocument || document ) ) {
5113					eventPath.push( tmp.defaultView || tmp.parentWindow || window );
5114				}
5115			}
5116
5117			// Fire handlers on the event path
5118			i = 0;
5119			while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
5120
5121				event.type = i > 1 ?
5122					bubbleType :
5123					special.bindType || type;
5124
5125				// jQuery handler
5126				handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
5127					jQuery._data( cur, "handle" );
5128
5129				if ( handle ) {
5130					handle.apply( cur, data );
5131				}
5132
5133				// Native handler
5134				handle = ontype && cur[ ontype ];
5135				if ( handle && handle.apply && acceptData( cur ) ) {
5136					event.result = handle.apply( cur, data );
5137					if ( event.result === false ) {
5138						event.preventDefault();
5139					}
5140				}
5141			}
5142			event.type = type;
5143
5144			// If nobody prevented the default action, do it now
5145			if ( !onlyHandlers && !event.isDefaultPrevented() ) {
5146
5147				if (
5148					( !special._default ||
5149						special._default.apply( eventPath.pop(), data ) === false
5150					) && acceptData( elem )
5151				) {
5152
5153					// Call a native DOM method on the target with the same name name as the event.
5154					// Can't use an .isFunction() check here because IE6/7 fails that test.
5155					// Don't do default actions on window, that's where global variables be (#6170)
5156					if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
5157
5158						// Don't re-trigger an onFOO event when we call its FOO() method
5159						tmp = elem[ ontype ];
5160
5161						if ( tmp ) {
5162							elem[ ontype ] = null;
5163						}
5164
5165						// Prevent re-triggering of the same event, since we already bubbled it above
5166						jQuery.event.triggered = type;
5167						try {
5168							elem[ type ]();
5169						} catch ( e ) {
5170
5171							// IE<9 dies on focus/blur to hidden element (#1486,#12518)
5172							// only reproducible on winXP IE8 native, not IE9 in IE8 mode
5173						}
5174						jQuery.event.triggered = undefined;
5175
5176						if ( tmp ) {
5177							elem[ ontype ] = tmp;
5178						}
5179					}
5180				}
5181			}
5182
5183			return event.result;
5184		},
5185
5186		dispatch: function( event ) {
5187
5188			// Make a writable jQuery.Event from the native event object
5189			event = jQuery.event.fix( event );
5190
5191			var i, j, ret, matched, handleObj,
5192				handlerQueue = [],
5193				args = slice.call( arguments ),
5194				handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
5195				special = jQuery.event.special[ event.type ] || {};
5196
5197			// Use the fix-ed jQuery.Event rather than the (read-only) native event
5198			args[ 0 ] = event;
5199			event.delegateTarget = this;
5200
5201			// Call the preDispatch hook for the mapped type, and let it bail if desired
5202			if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5203				return;
5204			}
5205
5206			// Determine handlers
5207			handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5208
5209			// Run delegates first; they may want to stop propagation beneath us
5210			i = 0;
5211			while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5212				event.currentTarget = matched.elem;
5213
5214				j = 0;
5215				while ( ( handleObj = matched.handlers[ j++ ] ) &&
5216				!event.isImmediatePropagationStopped() ) {
5217
5218					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
5219					// a subset or equal to those in the bound event (both can have no namespace).
5220					if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5221
5222						event.handleObj = handleObj;
5223						event.data = handleObj.data;
5224
5225						ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5226							handleObj.handler ).apply( matched.elem, args );
5227
5228						if ( ret !== undefined ) {
5229							if ( ( event.result = ret ) === false ) {
5230								event.preventDefault();
5231								event.stopPropagation();
5232							}
5233						}
5234					}
5235				}
5236			}
5237
5238			// Call the postDispatch hook for the mapped type
5239			if ( special.postDispatch ) {
5240				special.postDispatch.call( this, event );
5241			}
5242
5243			return event.result;
5244		},
5245
5246		handlers: function( event, handlers ) {
5247			var i, matches, sel, handleObj,
5248				handlerQueue = [],
5249				delegateCount = handlers.delegateCount,
5250				cur = event.target;
5251
5252			// Support (at least): Chrome, IE9
5253			// Find delegate handlers
5254			// Black-hole SVG <use> instance trees (#13180)
5255			//
5256			// Support: Firefox<=42+
5257			// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5258			if ( delegateCount && cur.nodeType &&
5259				( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
5260
5261				/* jshint eqeqeq: false */
5262				for ( ; cur != this; cur = cur.parentNode || this ) {
5263					/* jshint eqeqeq: true */
5264
5265					// Don't check non-elements (#13208)
5266					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5267					if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
5268						matches = [];
5269						for ( i = 0; i < delegateCount; i++ ) {
5270							handleObj = handlers[ i ];
5271
5272							// Don't conflict with Object.prototype properties (#13203)
5273							sel = handleObj.selector + " ";
5274
5275							if ( matches[ sel ] === undefined ) {
5276								matches[ sel ] = handleObj.needsContext ?
5277									jQuery( sel, this ).index( cur ) > -1 :
5278									jQuery.find( sel, this, null, [ cur ] ).length;
5279							}
5280							if ( matches[ sel ] ) {
5281								matches.push( handleObj );
5282							}
5283						}
5284						if ( matches.length ) {
5285							handlerQueue.push( { elem: cur, handlers: matches } );
5286						}
5287					}
5288				}
5289			}
5290
5291			// Add the remaining (directly-bound) handlers
5292			if ( delegateCount < handlers.length ) {
5293				handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
5294			}
5295
5296			return handlerQueue;
5297		},
5298
5299		fix: function( event ) {
5300			if ( event[ jQuery.expando ] ) {
5301				return event;
5302			}
5303
5304			// Create a writable copy of the event object and normalize some properties
5305			var i, prop, copy,
5306				type = event.type,
5307				originalEvent = event,
5308				fixHook = this.fixHooks[ type ];
5309
5310			if ( !fixHook ) {
5311				this.fixHooks[ type ] = fixHook =
5312					rmouseEvent.test( type ) ? this.mouseHooks :
5313						rkeyEvent.test( type ) ? this.keyHooks :
5314							{};
5315			}
5316			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
5317
5318			event = new jQuery.Event( originalEvent );
5319
5320			i = copy.length;
5321			while ( i-- ) {
5322				prop = copy[ i ];
5323				event[ prop ] = originalEvent[ prop ];
5324			}
5325
5326			// Support: IE<9
5327			// Fix target property (#1925)
5328			if ( !event.target ) {
5329				event.target = originalEvent.srcElement || document;
5330			}
5331
5332			// Support: Safari 6-8+
5333			// Target should not be a text node (#504, #13143)
5334			if ( event.target.nodeType === 3 ) {
5335				event.target = event.target.parentNode;
5336			}
5337
5338			// Support: IE<9
5339			// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
5340			event.metaKey = !!event.metaKey;
5341
5342			return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
5343		},
5344
5345		// Includes some event props shared by KeyEvent and MouseEvent
5346		props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
5347			"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
5348
5349		fixHooks: {},
5350
5351		keyHooks: {
5352			props: "char charCode key keyCode".split( " " ),
5353			filter: function( event, original ) {
5354
5355				// Add which for key events
5356				if ( event.which == null ) {
5357					event.which = original.charCode != null ? original.charCode : original.keyCode;
5358				}
5359
5360				return event;
5361			}
5362		},
5363
5364		mouseHooks: {
5365			props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
5366				"pageX pageY screenX screenY toElement" ).split( " " ),
5367			filter: function( event, original ) {
5368				var body, eventDoc, doc,
5369					button = original.button,
5370					fromElement = original.fromElement;
5371
5372				// Calculate pageX/Y if missing and clientX/Y available
5373				if ( event.pageX == null && original.clientX != null ) {
5374					eventDoc = event.target.ownerDocument || document;
5375					doc = eventDoc.documentElement;
5376					body = eventDoc.body;
5377
5378					event.pageX = original.clientX +
5379						( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
5380						( doc && doc.clientLeft || body && body.clientLeft || 0 );
5381					event.pageY = original.clientY +
5382						( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
5383						( doc && doc.clientTop  || body && body.clientTop  || 0 );
5384				}
5385
5386				// Add relatedTarget, if necessary
5387				if ( !event.relatedTarget && fromElement ) {
5388					event.relatedTarget = fromElement === event.target ?
5389						original.toElement :
5390						fromElement;
5391				}
5392
5393				// Add which for click: 1 === left; 2 === middle; 3 === right
5394				// Note: button is not normalized, so don't use it
5395				if ( !event.which && button !== undefined ) {
5396					event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
5397				}
5398
5399				return event;
5400			}
5401		},
5402
5403		special: {
5404			load: {
5405
5406				// Prevent triggered image.load events from bubbling to window.load
5407				noBubble: true
5408			},
5409			focus: {
5410
5411				// Fire native event if possible so blur/focus sequence is correct
5412				trigger: function() {
5413					if ( this !== safeActiveElement() && this.focus ) {
5414						try {
5415							this.focus();
5416							return false;
5417						} catch ( e ) {
5418
5419							// Support: IE<9
5420							// If we error on focus to hidden element (#1486, #12518),
5421							// let .trigger() run the handlers
5422						}
5423					}
5424				},
5425				delegateType: "focusin"
5426			},
5427			blur: {
5428				trigger: function() {
5429					if ( this === safeActiveElement() && this.blur ) {
5430						this.blur();
5431						return false;
5432					}
5433				},
5434				delegateType: "focusout"
5435			},
5436			click: {
5437
5438				// For checkbox, fire native event so checked state will be right
5439				trigger: function() {
5440					if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
5441						this.click();
5442						return false;
5443					}
5444				},
5445
5446				// For cross-browser consistency, don't fire native .click() on links
5447				_default: function( event ) {
5448					return jQuery.nodeName( event.target, "a" );
5449				}
5450			},
5451
5452			beforeunload: {
5453				postDispatch: function( event ) {
5454
5455					// Support: Firefox 20+
5456					// Firefox doesn't alert if the returnValue field is not set.
5457					if ( event.result !== undefined && event.originalEvent ) {
5458						event.originalEvent.returnValue = event.result;
5459					}
5460				}
5461			}
5462		},
5463
5464		// Piggyback on a donor event to simulate a different one
5465		simulate: function( type, elem, event ) {
5466			var e = jQuery.extend(
5467				new jQuery.Event(),
5468				event,
5469				{
5470					type: type,
5471					isSimulated: true
5472
5473					// Previously, `originalEvent: {}` was set here, so stopPropagation call
5474					// would not be triggered on donor event, since in our own
5475					// jQuery.event.stopPropagation function we had a check for existence of
5476					// originalEvent.stopPropagation method, so, consequently it would be a noop.
5477					//
5478					// Guard for simulated events was moved to jQuery.event.stopPropagation function
5479					// since `originalEvent` should point to the original event for the
5480					// constancy with other events and for more focused logic
5481				}
5482			);
5483
5484			jQuery.event.trigger( e, null, elem );
5485
5486			if ( e.isDefaultPrevented() ) {
5487				event.preventDefault();
5488			}
5489		}
5490	};
5491
5492	jQuery.removeEvent = document.removeEventListener ?
5493		function( elem, type, handle ) {
5494
5495			// This "if" is needed for plain objects
5496			if ( elem.removeEventListener ) {
5497				elem.removeEventListener( type, handle );
5498			}
5499		} :
5500		function( elem, type, handle ) {
5501			var name = "on" + type;
5502
5503			if ( elem.detachEvent ) {
5504
5505				// #8545, #7054, preventing memory leaks for custom events in IE6-8
5506				// detachEvent needed property on element, by name of that event,
5507				// to properly expose it to GC
5508				if ( typeof elem[ name ] === "undefined" ) {
5509					elem[ name ] = null;
5510				}
5511
5512				elem.detachEvent( name, handle );
5513			}
5514		};
5515
5516	jQuery.Event = function( src, props ) {
5517
5518		// Allow instantiation without the 'new' keyword
5519		if ( !( this instanceof jQuery.Event ) ) {
5520			return new jQuery.Event( src, props );
5521		}
5522
5523		// Event object
5524		if ( src && src.type ) {
5525			this.originalEvent = src;
5526			this.type = src.type;
5527
5528			// Events bubbling up the document may have been marked as prevented
5529			// by a handler lower down the tree; reflect the correct value.
5530			this.isDefaultPrevented = src.defaultPrevented ||
5531			src.defaultPrevented === undefined &&
5532
5533			// Support: IE < 9, Android < 4.0
5534			src.returnValue === false ?
5535				returnTrue :
5536				returnFalse;
5537
5538			// Event type
5539		} else {
5540			this.type = src;
5541		}
5542
5543		// Put explicitly provided properties onto the event object
5544		if ( props ) {
5545			jQuery.extend( this, props );
5546		}
5547
5548		// Create a timestamp if incoming event doesn't have one
5549		this.timeStamp = src && src.timeStamp || jQuery.now();
5550
5551		// Mark it as fixed
5552		this[ jQuery.expando ] = true;
5553	};
5554
5555// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5556// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5557	jQuery.Event.prototype = {
5558		constructor: jQuery.Event,
5559		isDefaultPrevented: returnFalse,
5560		isPropagationStopped: returnFalse,
5561		isImmediatePropagationStopped: returnFalse,
5562
5563		preventDefault: function() {
5564			var e = this.originalEvent;
5565
5566			this.isDefaultPrevented = returnTrue;
5567			if ( !e ) {
5568				return;
5569			}
5570
5571			// If preventDefault exists, run it on the original event
5572			if ( e.preventDefault ) {
5573				e.preventDefault();
5574
5575				// Support: IE
5576				// Otherwise set the returnValue property of the original event to false
5577			} else {
5578				e.returnValue = false;
5579			}
5580		},
5581		stopPropagation: function() {
5582			var e = this.originalEvent;
5583
5584			this.isPropagationStopped = returnTrue;
5585
5586			if ( !e || this.isSimulated ) {
5587				return;
5588			}
5589
5590			// If stopPropagation exists, run it on the original event
5591			if ( e.stopPropagation ) {
5592				e.stopPropagation();
5593			}
5594
5595			// Support: IE
5596			// Set the cancelBubble property of the original event to true
5597			e.cancelBubble = true;
5598		},
5599		stopImmediatePropagation: function() {
5600			var e = this.originalEvent;
5601
5602			this.isImmediatePropagationStopped = returnTrue;
5603
5604			if ( e && e.stopImmediatePropagation ) {
5605				e.stopImmediatePropagation();
5606			}
5607
5608			this.stopPropagation();
5609		}
5610	};
5611
5612// Create mouseenter/leave events using mouseover/out and event-time checks
5613// so that event delegation works in jQuery.
5614// Do the same for pointerenter/pointerleave and pointerover/pointerout
5615//
5616// Support: Safari 7 only
5617// Safari sends mouseenter too often; see:
5618// https://code.google.com/p/chromium/issues/detail?id=470258
5619// for the description of the bug (it existed in older Chrome versions as well).
5620	jQuery.each( {
5621		mouseenter: "mouseover",
5622		mouseleave: "mouseout",
5623		pointerenter: "pointerover",
5624		pointerleave: "pointerout"
5625	}, function( orig, fix ) {
5626		jQuery.event.special[ orig ] = {
5627			delegateType: fix,
5628			bindType: fix,
5629
5630			handle: function( event ) {
5631				var ret,
5632					target = this,
5633					related = event.relatedTarget,
5634					handleObj = event.handleObj;
5635
5636				// For mouseenter/leave call the handler if related is outside the target.
5637				// NB: No relatedTarget if the mouse left/entered the browser window
5638				if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5639					event.type = handleObj.origType;
5640					ret = handleObj.handler.apply( this, arguments );
5641					event.type = fix;
5642				}
5643				return ret;
5644			}
5645		};
5646	} );
5647
5648// IE submit delegation
5649	if ( !support.submit ) {
5650
5651		jQuery.event.special.submit = {
5652			setup: function() {
5653
5654				// Only need this for delegated form submit events
5655				if ( jQuery.nodeName( this, "form" ) ) {
5656					return false;
5657				}
5658
5659				// Lazy-add a submit handler when a descendant form may potentially be submitted
5660				jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5661
5662					// Node name check avoids a VML-related crash in IE (#9807)
5663					var elem = e.target,
5664						form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
5665
5666							// Support: IE <=8
5667							// We use jQuery.prop instead of elem.form
5668							// to allow fixing the IE8 delegated submit issue (gh-2332)
5669							// by 3rd party polyfills/workarounds.
5670							jQuery.prop( elem, "form" ) :
5671							undefined;
5672
5673					if ( form && !jQuery._data( form, "submit" ) ) {
5674						jQuery.event.add( form, "submit._submit", function( event ) {
5675							event._submitBubble = true;
5676						} );
5677						jQuery._data( form, "submit", true );
5678					}
5679				} );
5680
5681				// return undefined since we don't need an event listener
5682			},
5683
5684			postDispatch: function( event ) {
5685
5686				// If form was submitted by the user, bubble the event up the tree
5687				if ( event._submitBubble ) {
5688					delete event._submitBubble;
5689					if ( this.parentNode && !event.isTrigger ) {
5690						jQuery.event.simulate( "submit", this.parentNode, event );
5691					}
5692				}
5693			},
5694
5695			teardown: function() {
5696
5697				// Only need this for delegated form submit events
5698				if ( jQuery.nodeName( this, "form" ) ) {
5699					return false;
5700				}
5701
5702				// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5703				jQuery.event.remove( this, "._submit" );
5704			}
5705		};
5706	}
5707
5708// IE change delegation and checkbox/radio fix
5709	if ( !support.change ) {
5710
5711		jQuery.event.special.change = {
5712
5713			setup: function() {
5714
5715				if ( rformElems.test( this.nodeName ) ) {
5716
5717					// IE doesn't fire change on a check/radio until blur; trigger it on click
5718					// after a propertychange. Eat the blur-change in special.change.handle.
5719					// This still fires onchange a second time for check/radio after blur.
5720					if ( this.type === "checkbox" || this.type === "radio" ) {
5721						jQuery.event.add( this, "propertychange._change", function( event ) {
5722							if ( event.originalEvent.propertyName === "checked" ) {
5723								this._justChanged = true;
5724							}
5725						} );
5726						jQuery.event.add( this, "click._change", function( event ) {
5727							if ( this._justChanged && !event.isTrigger ) {
5728								this._justChanged = false;
5729							}
5730
5731							// Allow triggered, simulated change events (#11500)
5732							jQuery.event.simulate( "change", this, event );
5733						} );
5734					}
5735					return false;
5736				}
5737
5738				// Delegated event; lazy-add a change handler on descendant inputs
5739				jQuery.event.add( this, "beforeactivate._change", function( e ) {
5740					var elem = e.target;
5741
5742					if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
5743						jQuery.event.add( elem, "change._change", function( event ) {
5744							if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5745								jQuery.event.simulate( "change", this.parentNode, event );
5746							}
5747						} );
5748						jQuery._data( elem, "change", true );
5749					}
5750				} );
5751			},
5752
5753			handle: function( event ) {
5754				var elem = event.target;
5755
5756				// Swallow native change events from checkbox/radio, we already triggered them above
5757				if ( this !== elem || event.isSimulated || event.isTrigger ||
5758					( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
5759
5760					return event.handleObj.handler.apply( this, arguments );
5761				}
5762			},
5763
5764			teardown: function() {
5765				jQuery.event.remove( this, "._change" );
5766
5767				return !rformElems.test( this.nodeName );
5768			}
5769		};
5770	}
5771
5772// Support: Firefox
5773// Firefox doesn't have focus(in | out) events
5774// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5775//
5776// Support: Chrome, Safari
5777// focus(in | out) events fire after focus & blur events,
5778// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5779// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
5780	if ( !support.focusin ) {
5781		jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5782
5783			// Attach a single capturing handler on the document while someone wants focusin/focusout
5784			var handler = function( event ) {
5785				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
5786			};
5787
5788			jQuery.event.special[ fix ] = {
5789				setup: function() {
5790					var doc = this.ownerDocument || this,
5791						attaches = jQuery._data( doc, fix );
5792
5793					if ( !attaches ) {
5794						doc.addEventListener( orig, handler, true );
5795					}
5796					jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5797				},
5798				teardown: function() {
5799					var doc = this.ownerDocument || this,
5800						attaches = jQuery._data( doc, fix ) - 1;
5801
5802					if ( !attaches ) {
5803						doc.removeEventListener( orig, handler, true );
5804						jQuery._removeData( doc, fix );
5805					} else {
5806						jQuery._data( doc, fix, attaches );
5807					}
5808				}
5809			};
5810		} );
5811	}
5812
5813	jQuery.fn.extend( {
5814
5815		on: function( types, selector, data, fn ) {
5816			return on( this, types, selector, data, fn );
5817		},
5818		one: function( types, selector, data, fn ) {
5819			return on( this, types, selector, data, fn, 1 );
5820		},
5821		off: function( types, selector, fn ) {
5822			var handleObj, type;
5823			if ( types && types.preventDefault && types.handleObj ) {
5824
5825				// ( event )  dispatched jQuery.Event
5826				handleObj = types.handleObj;
5827				jQuery( types.delegateTarget ).off(
5828					handleObj.namespace ?
5829						handleObj.origType + "." + handleObj.namespace :
5830						handleObj.origType,
5831					handleObj.selector,
5832					handleObj.handler
5833				);
5834				return this;
5835			}
5836			if ( typeof types === "object" ) {
5837
5838				// ( types-object [, selector] )
5839				for ( type in types ) {
5840					this.off( type, selector, types[ type ] );
5841				}
5842				return this;
5843			}
5844			if ( selector === false || typeof selector === "function" ) {
5845
5846				// ( types [, fn] )
5847				fn = selector;
5848				selector = undefined;
5849			}
5850			if ( fn === false ) {
5851				fn = returnFalse;
5852			}
5853			return this.each( function() {
5854				jQuery.event.remove( this, types, fn, selector );
5855			} );
5856		},
5857
5858		trigger: function( type, data ) {
5859			return this.each( function() {
5860				jQuery.event.trigger( type, data, this );
5861			} );
5862		},
5863		triggerHandler: function( type, data ) {
5864			var elem = this[ 0 ];
5865			if ( elem ) {
5866				return jQuery.event.trigger( type, data, elem, true );
5867			}
5868		}
5869	} );
5870
5871
5872	var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5873		rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
5874		rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5875
5876		// Support: IE 10-11, Edge 10240+
5877		// In IE/Edge using regex groups here causes severe slowdowns.
5878		// See https://connect.microsoft.com/IE/feedback/details/1736512/
5879		rnoInnerhtml = /<script|<style|<link/i,
5880
5881		// checked="checked" or checked
5882		rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5883		rscriptTypeMasked = /^true\/(.*)/,
5884		rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5885		safeFragment = createSafeFragment( document ),
5886		fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
5887
5888// Support: IE<8
5889// Manipulating tables requires a tbody
5890	function manipulationTarget( elem, content ) {
5891		return jQuery.nodeName( elem, "table" ) &&
5892		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5893
5894			elem.getElementsByTagName( "tbody" )[ 0 ] ||
5895			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5896			elem;
5897	}
5898
5899// Replace/restore the type attribute of script elements for safe DOM manipulation
5900	function disableScript( elem ) {
5901		elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
5902		return elem;
5903	}
5904	function restoreScript( elem ) {
5905		var match = rscriptTypeMasked.exec( elem.type );
5906		if ( match ) {
5907			elem.type = match[ 1 ];
5908		} else {
5909			elem.removeAttribute( "type" );
5910		}
5911		return elem;
5912	}
5913
5914	function cloneCopyEvent( src, dest ) {
5915		if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5916			return;
5917		}
5918
5919		var type, i, l,
5920			oldData = jQuery._data( src ),
5921			curData = jQuery._data( dest, oldData ),
5922			events = oldData.events;
5923
5924		if ( events ) {
5925			delete curData.handle;
5926			curData.events = {};
5927
5928			for ( type in events ) {
5929				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5930					jQuery.event.add( dest, type, events[ type ][ i ] );
5931				}
5932			}
5933		}
5934
5935		// make the cloned public data object a copy from the original
5936		if ( curData.data ) {
5937			curData.data = jQuery.extend( {}, curData.data );
5938		}
5939	}
5940
5941	function fixCloneNodeIssues( src, dest ) {
5942		var nodeName, e, data;
5943
5944		// We do not need to do anything for non-Elements
5945		if ( dest.nodeType !== 1 ) {
5946			return;
5947		}
5948
5949		nodeName = dest.nodeName.toLowerCase();
5950
5951		// IE6-8 copies events bound via attachEvent when using cloneNode.
5952		if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5953			data = jQuery._data( dest );
5954
5955			for ( e in data.events ) {
5956				jQuery.removeEvent( dest, e, data.handle );
5957			}
5958
5959			// Event data gets referenced instead of copied if the expando gets copied too
5960			dest.removeAttribute( jQuery.expando );
5961		}
5962
5963		// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5964		if ( nodeName === "script" && dest.text !== src.text ) {
5965			disableScript( dest ).text = src.text;
5966			restoreScript( dest );
5967
5968			// IE6-10 improperly clones children of object elements using classid.
5969			// IE10 throws NoModificationAllowedError if parent is null, #12132.
5970		} else if ( nodeName === "object" ) {
5971			if ( dest.parentNode ) {
5972				dest.outerHTML = src.outerHTML;
5973			}
5974
5975			// This path appears unavoidable for IE9. When cloning an object
5976			// element in IE9, the outerHTML strategy above is not sufficient.
5977			// If the src has innerHTML and the destination does not,
5978			// copy the src.innerHTML into the dest.innerHTML. #10324
5979			if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
5980				dest.innerHTML = src.innerHTML;
5981			}
5982
5983		} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5984
5985			// IE6-8 fails to persist the checked state of a cloned checkbox
5986			// or radio button. Worse, IE6-7 fail to give the cloned element
5987			// a checked appearance if the defaultChecked value isn't also set
5988
5989			dest.defaultChecked = dest.checked = src.checked;
5990
5991			// IE6-7 get confused and end up setting the value of a cloned
5992			// checkbox/radio button to an empty string instead of "on"
5993			if ( dest.value !== src.value ) {
5994				dest.value = src.value;
5995			}
5996
5997			// IE6-8 fails to return the selected option to the default selected
5998			// state when cloning options
5999		} else if ( nodeName === "option" ) {
6000			dest.defaultSelected = dest.selected = src.defaultSelected;
6001
6002			// IE6-8 fails to set the defaultValue to the correct value when
6003			// cloning other types of input fields
6004		} else if ( nodeName === "input" || nodeName === "textarea" ) {
6005			dest.defaultValue = src.defaultValue;
6006		}
6007	}
6008
6009	function domManip( collection, args, callback, ignored ) {
6010
6011		// Flatten any nested arrays
6012		args = concat.apply( [], args );
6013
6014		var first, node, hasScripts,
6015			scripts, doc, fragment,
6016			i = 0,
6017			l = collection.length,
6018			iNoClone = l - 1,
6019			value = args[ 0 ],
6020			isFunction = jQuery.isFunction( value );
6021
6022		// We can't cloneNode fragments that contain checked, in WebKit
6023		if ( isFunction ||
6024			( l > 1 && typeof value === "string" &&
6025				!support.checkClone && rchecked.test( value ) ) ) {
6026			return collection.each( function( index ) {
6027				var self = collection.eq( index );
6028				if ( isFunction ) {
6029					args[ 0 ] = value.call( this, index, self.html() );
6030				}
6031				domManip( self, args, callback, ignored );
6032			} );
6033		}
6034
6035		if ( l ) {
6036			fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6037			first = fragment.firstChild;
6038
6039			if ( fragment.childNodes.length === 1 ) {
6040				fragment = first;
6041			}
6042
6043			// Require either new content or an interest in ignored elements to invoke the callback
6044			if ( first || ignored ) {
6045				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6046				hasScripts = scripts.length;
6047
6048				// Use the original fragment for the last item
6049				// instead of the first because it can end up
6050				// being emptied incorrectly in certain situations (#8070).
6051				for ( ; i < l; i++ ) {
6052					node = fragment;
6053
6054					if ( i !== iNoClone ) {
6055						node = jQuery.clone( node, true, true );
6056
6057						// Keep references to cloned scripts for later restoration
6058						if ( hasScripts ) {
6059
6060							// Support: Android<4.1, PhantomJS<2
6061							// push.apply(_, arraylike) throws on ancient WebKit
6062							jQuery.merge( scripts, getAll( node, "script" ) );
6063						}
6064					}
6065
6066					callback.call( collection[ i ], node, i );
6067				}
6068
6069				if ( hasScripts ) {
6070					doc = scripts[ scripts.length - 1 ].ownerDocument;
6071
6072					// Reenable scripts
6073					jQuery.map( scripts, restoreScript );
6074
6075					// Evaluate executable scripts on first document insertion
6076					for ( i = 0; i < hasScripts; i++ ) {
6077						node = scripts[ i ];
6078						if ( rscriptType.test( node.type || "" ) &&
6079							!jQuery._data( node, "globalEval" ) &&
6080							jQuery.contains( doc, node ) ) {
6081
6082							if ( node.src ) {
6083
6084								// Optional AJAX dependency, but won't run scripts if not present
6085								if ( jQuery._evalUrl ) {
6086									jQuery._evalUrl( node.src );
6087								}
6088							} else {
6089								jQuery.globalEval(
6090									( node.text || node.textContent || node.innerHTML || "" )
6091										.replace( rcleanScript, "" )
6092								);
6093							}
6094						}
6095					}
6096				}
6097
6098				// Fix #11809: Avoid leaking memory
6099				fragment = first = null;
6100			}
6101		}
6102
6103		return collection;
6104	}
6105
6106	function remove( elem, selector, keepData ) {
6107		var node,
6108			elems = selector ? jQuery.filter( selector, elem ) : elem,
6109			i = 0;
6110
6111		for ( ; ( node = elems[ i ] ) != null; i++ ) {
6112
6113			if ( !keepData && node.nodeType === 1 ) {
6114				jQuery.cleanData( getAll( node ) );
6115			}
6116
6117			if ( node.parentNode ) {
6118				if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
6119					setGlobalEval( getAll( node, "script" ) );
6120				}
6121				node.parentNode.removeChild( node );
6122			}
6123		}
6124
6125		return elem;
6126	}
6127
6128	jQuery.extend( {
6129		htmlPrefilter: function( html ) {
6130			return html.replace( rxhtmlTag, "<$1></$2>" );
6131		},
6132
6133		clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6134			var destElements, node, clone, i, srcElements,
6135				inPage = jQuery.contains( elem.ownerDocument, elem );
6136
6137			if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
6138				!rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6139
6140				clone = elem.cloneNode( true );
6141
6142				// IE<=8 does not properly clone detached, unknown element nodes
6143			} else {
6144				fragmentDiv.innerHTML = elem.outerHTML;
6145				fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6146			}
6147
6148			if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
6149				( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
6150
6151				// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
6152				destElements = getAll( clone );
6153				srcElements = getAll( elem );
6154
6155				// Fix all IE cloning issues
6156				for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
6157
6158					// Ensure that the destination node is not null; Fixes #9587
6159					if ( destElements[ i ] ) {
6160						fixCloneNodeIssues( node, destElements[ i ] );
6161					}
6162				}
6163			}
6164
6165			// Copy the events from the original to the clone
6166			if ( dataAndEvents ) {
6167				if ( deepDataAndEvents ) {
6168					srcElements = srcElements || getAll( elem );
6169					destElements = destElements || getAll( clone );
6170
6171					for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
6172						cloneCopyEvent( node, destElements[ i ] );
6173					}
6174				} else {
6175					cloneCopyEvent( elem, clone );
6176				}
6177			}
6178
6179			// Preserve script evaluation history
6180			destElements = getAll( clone, "script" );
6181			if ( destElements.length > 0 ) {
6182				setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6183			}
6184
6185			destElements = srcElements = node = null;
6186
6187			// Return the cloned set
6188			return clone;
6189		},
6190
6191		cleanData: function( elems, /* internal */ forceAcceptData ) {
6192			var elem, type, id, data,
6193				i = 0,
6194				internalKey = jQuery.expando,
6195				cache = jQuery.cache,
6196				attributes = support.attributes,
6197				special = jQuery.event.special;
6198
6199			for ( ; ( elem = elems[ i ] ) != null; i++ ) {
6200				if ( forceAcceptData || acceptData( elem ) ) {
6201
6202					id = elem[ internalKey ];
6203					data = id && cache[ id ];
6204
6205					if ( data ) {
6206						if ( data.events ) {
6207							for ( type in data.events ) {
6208								if ( special[ type ] ) {
6209									jQuery.event.remove( elem, type );
6210
6211									// This is a shortcut to avoid jQuery.event.remove's overhead
6212								} else {
6213									jQuery.removeEvent( elem, type, data.handle );
6214								}
6215							}
6216						}
6217
6218						// Remove cache only if it was not already removed by jQuery.event.remove
6219						if ( cache[ id ] ) {
6220
6221							delete cache[ id ];
6222
6223							// Support: IE<9
6224							// IE does not allow us to delete expando properties from nodes
6225							// IE creates expando attributes along with the property
6226							// IE does not have a removeAttribute function on Document nodes
6227							if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
6228								elem.removeAttribute( internalKey );
6229
6230								// Webkit & Blink performance suffers when deleting properties
6231								// from DOM nodes, so set to undefined instead
6232								// https://code.google.com/p/chromium/issues/detail?id=378607
6233							} else {
6234								elem[ internalKey ] = undefined;
6235							}
6236
6237							deletedIds.push( id );
6238						}
6239					}
6240				}
6241			}
6242		}
6243	} );
6244
6245	jQuery.fn.extend( {
6246
6247		// Keep domManip exposed until 3.0 (gh-2225)
6248		domManip: domManip,
6249
6250		detach: function( selector ) {
6251			return remove( this, selector, true );
6252		},
6253
6254		remove: function( selector ) {
6255			return remove( this, selector );
6256		},
6257
6258		text: function( value ) {
6259			return access( this, function( value ) {
6260				return value === undefined ?
6261					jQuery.text( this ) :
6262					this.empty().append(
6263						( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
6264					);
6265			}, null, value, arguments.length );
6266		},
6267
6268		append: function() {
6269			return domManip( this, arguments, function( elem ) {
6270				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6271					var target = manipulationTarget( this, elem );
6272					target.appendChild( elem );
6273				}
6274			} );
6275		},
6276
6277		prepend: function() {
6278			return domManip( this, arguments, function( elem ) {
6279				if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6280					var target = manipulationTarget( this, elem );
6281					target.insertBefore( elem, target.firstChild );
6282				}
6283			} );
6284		},
6285
6286		before: function() {
6287			return domManip( this, arguments, function( elem ) {
6288				if ( this.parentNode ) {
6289					this.parentNode.insertBefore( elem, this );
6290				}
6291			} );
6292		},
6293
6294		after: function() {
6295			return domManip( this, arguments, function( elem ) {
6296				if ( this.parentNode ) {
6297					this.parentNode.insertBefore( elem, this.nextSibling );
6298				}
6299			} );
6300		},
6301
6302		empty: function() {
6303			var elem,
6304				i = 0;
6305
6306			for ( ; ( elem = this[ i ] ) != null; i++ ) {
6307
6308				// Remove element nodes and prevent memory leaks
6309				if ( elem.nodeType === 1 ) {
6310					jQuery.cleanData( getAll( elem, false ) );
6311				}
6312
6313				// Remove any remaining nodes
6314				while ( elem.firstChild ) {
6315					elem.removeChild( elem.firstChild );
6316				}
6317
6318				// If this is a select, ensure that it displays empty (#12336)
6319				// Support: IE<9
6320				if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
6321					elem.options.length = 0;
6322				}
6323			}
6324
6325			return this;
6326		},
6327
6328		clone: function( dataAndEvents, deepDataAndEvents ) {
6329			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6330			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6331
6332			return this.map( function() {
6333				return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6334			} );
6335		},
6336
6337		html: function( value ) {
6338			return access( this, function( value ) {
6339				var elem = this[ 0 ] || {},
6340					i = 0,
6341					l = this.length;
6342
6343				if ( value === undefined ) {
6344					return elem.nodeType === 1 ?
6345						elem.innerHTML.replace( rinlinejQuery, "" ) :
6346						undefined;
6347				}
6348
6349				// See if we can take a shortcut and just use innerHTML
6350				if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6351					( support.htmlSerialize || !rnoshimcache.test( value )  ) &&
6352					( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
6353					!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6354
6355					value = jQuery.htmlPrefilter( value );
6356
6357					try {
6358						for ( ; i < l; i++ ) {
6359
6360							// Remove element nodes and prevent memory leaks
6361							elem = this[ i ] || {};
6362							if ( elem.nodeType === 1 ) {
6363								jQuery.cleanData( getAll( elem, false ) );
6364								elem.innerHTML = value;
6365							}
6366						}
6367
6368						elem = 0;
6369
6370						// If using innerHTML throws an exception, use the fallback method
6371					} catch ( e ) {}
6372				}
6373
6374				if ( elem ) {
6375					this.empty().append( value );
6376				}
6377			}, null, value, arguments.length );
6378		},
6379
6380		replaceWith: function() {
6381			var ignored = [];
6382
6383			// Make the changes, replacing each non-ignored context element with the new content
6384			return domManip( this, arguments, function( elem ) {
6385				var parent = this.parentNode;
6386
6387				if ( jQuery.inArray( this, ignored ) < 0 ) {
6388					jQuery.cleanData( getAll( this ) );
6389					if ( parent ) {
6390						parent.replaceChild( elem, this );
6391					}
6392				}
6393
6394				// Force callback invocation
6395			}, ignored );
6396		}
6397	} );
6398
6399	jQuery.each( {
6400		appendTo: "append",
vendor: 1,226 bytes, lines 6401-6450
6401		prependTo: "prepend",
6402		insertBefore: "before",
6403		insertAfter: "after",
6404		replaceAll: "replaceWith"
6405	}, function( name, original ) {
6406		jQuery.fn[ name ] = function( selector ) {
6407			var elems,
6408				i = 0,
6409				ret = [],
6410				insert = jQuery( selector ),
6411				last = insert.length - 1;
6412
6413			for ( ; i <= last; i++ ) {
6414				elems = i === last ? this : this.clone( true );
6415				jQuery( insert[ i ] )[ original ]( elems );
6416
6417				// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6418				push.apply( ret, elems.get() );
6419			}
6420
6421			return this.pushStack( ret );
6422		};
6423	} );
6424
6425
6426	var iframe,
6427		elemdisplay = {
6428
6429			// Support: Firefox
6430			// We have to pre-define these values for FF (#10227)
6431			HTML: "block",
6432			BODY: "block"
6433		};
6434
6435	/**
6436	 * Retrieve the actual display of a element
6437	 * @param {String} name nodeName of the element
6438	 * @param {Object} doc Document object
6439	 */
6440
6441// Called only from within defaultDisplay
6442	function actualDisplay( name, doc ) {
6443		var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6444
6445			display = jQuery.css( elem[ 0 ], "display" );
6446
6447		// We don't have any data stored on the element,
6448		// so use "detach" method as fast way to get rid of the element
6449		elem.detach();
6450
6451		return display;
6452	}
6453
6454	/**
6455	 * Try to determine the default display value of an element
6456	 * @param {String} nodeName
6457	 */
6458	function defaultDisplay( nodeName ) {
6459		var doc = document,
6460			display = elemdisplay[ nodeName ];
6461
6462		if ( !display ) {
6463			display = actualDisplay( nodeName, doc );
6464
6465			// If the simple way fails, read from inside an iframe
6466			if ( display === "none" || !display ) {
6467
6468				// Use the already-created iframe if possible
6469				iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
6470					.appendTo( doc.documentElement );
6471
6472				// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6473				doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6474
6475				// Support: IE
6476				doc.write();
6477				doc.close();
6478
6479				display = actualDisplay( nodeName, doc );
6480				iframe.detach();
6481			}
6482
6483			// Store the correct default display
6484			elemdisplay[ nodeName ] = display;
6485		}
6486
6487		return display;
6488	}
6489	var rmargin = ( /^margin/ );
6490
6491	var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6492
6493	var swap = function( elem, options, callback, args ) {
6494		var ret, name,
6495			old = {};
6496
6497		// Remember the old values, and insert the new ones
6498		for ( name in options ) {
6499			old[ name ] = elem.style[ name ];
6500			elem.style[ name ] = options[ name ];
6501		}
6502
6503		ret = callback.apply( elem, args || [] );
6504
6505		// Revert the old values
6506		for ( name in options ) {
6507			elem.style[ name ] = old[ name ];
6508		}
6509
6510		return ret;
6511	};
6512
6513
6514	var documentElement = document.documentElement;
6515
6516
6517
6518	( function() {
6519		var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
6520			reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
6521			container = document.createElement( "div" ),
6522			div = document.createElement( "div" );
6523
6524		// Finish early in limited (non-browser) environments
6525		if ( !div.style ) {
6526			return;
6527		}
6528
6529		div.style.cssText = "float:left;opacity:.5";
6530
6531		// Support: IE<9
6532		// Make sure that element opacity exists (as opposed to filter)
6533		support.opacity = div.style.opacity === "0.5";
6534
6535		// Verify style float existence
6536		// (IE uses styleFloat instead of cssFloat)
6537		support.cssFloat = !!div.style.cssFloat;
6538
6539		div.style.backgroundClip = "content-box";
6540		div.cloneNode( true ).style.backgroundClip = "";
6541		support.clearCloneStyle = div.style.backgroundClip === "content-box";
6542
6543		container = document.createElement( "div" );
6544		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6545			"padding:0;margin-top:1px;position:absolute";
6546		div.innerHTML = "";
6547		container.appendChild( div );
6548
6549		// Support: Firefox<29, Android 2.3
6550		// Vendor-prefix box-sizing
6551		support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
6552			div.style.WebkitBoxSizing === "";
6553
6554		jQuery.extend( support, {
6555			reliableHiddenOffsets: function() {
6556				if ( pixelPositionVal == null ) {
6557					computeStyleTests();
6558				}
6559				return reliableHiddenOffsetsVal;
6560			},
6561
6562			boxSizingReliable: function() {
6563
6564				// We're checking for pixelPositionVal here instead of boxSizingReliableVal
6565				// since that compresses better and they're computed together anyway.
6566				if ( pixelPositionVal == null ) {
6567					computeStyleTests();
6568				}
6569				return boxSizingReliableVal;
6570			},
6571
6572			pixelMarginRight: function() {
6573
6574				// Support: Android 4.0-4.3
6575				if ( pixelPositionVal == null ) {
6576					computeStyleTests();
6577				}
6578				return pixelMarginRightVal;
6579			},
6580
6581			pixelPosition: function() {
6582				if ( pixelPositionVal == null ) {
6583					computeStyleTests();
6584				}
6585				return pixelPositionVal;
6586			},
6587
6588			reliableMarginRight: function() {
6589
6590				// Support: Android 2.3
6591				if ( pixelPositionVal == null ) {
6592					computeStyleTests();
6593				}
6594				return reliableMarginRightVal;
6595			},
6596
6597			reliableMarginLeft: function() {
6598
6599				// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6600				if ( pixelPositionVal == null ) {
6601					computeStyleTests();
6602				}
6603				return reliableMarginLeftVal;
6604			}
6605		} );
6606
6607		function computeStyleTests() {
6608			var contents, divStyle,
6609				documentElement = document.documentElement;
6610
6611			// Setup
6612			documentElement.appendChild( container );
6613
6614			div.style.cssText =
6615
6616				// Support: Android 2.3
6617				// Vendor-prefix box-sizing
6618				"-webkit-box-sizing:border-box;box-sizing:border-box;" +
6619				"position:relative;display:block;" +
6620				"margin:auto;border:1px;padding:1px;" +
6621				"top:1%;width:50%";
6622
6623			// Support: IE<9
6624			// Assume reasonable values in the absence of getComputedStyle
6625			pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
6626			pixelMarginRightVal = reliableMarginRightVal = true;
6627
6628			// Check for getComputedStyle so that this code is not run in IE<9.
6629			if ( window.getComputedStyle ) {
6630				divStyle = window.getComputedStyle( div );
6631				pixelPositionVal = ( divStyle || {} ).top !== "1%";
6632				reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
6633				boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
6634
6635				// Support: Android 4.0 - 4.3 only
6636				// Some styles come back with percentage values, even though they shouldn't
6637				div.style.marginRight = "50%";
6638				pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
6639
6640				// Support: Android 2.3 only
6641				// Div with explicit width and no margin-right incorrectly
6642				// gets computed margin-right based on width of container (#3333)
6643				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6644				contents = div.appendChild( document.createElement( "div" ) );
6645
6646				// Reset CSS: box-sizing; display; margin; border; padding
6647				contents.style.cssText = div.style.cssText =
6648
6649					// Support: Android 2.3
6650					// Vendor-prefix box-sizing
6651					"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6652					"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6653				contents.style.marginRight = contents.style.width = "0";
6654				div.style.width = "1px";
6655
6656				reliableMarginRightVal =
6657					!parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
6658
6659				div.removeChild( contents );
6660			}
6661
6662			// Support: IE6-8
6663			// First check that getClientRects works as expected
6664			// Check if table cells still have offsetWidth/Height when they are set
6665			// to display:none and there are still other visible table cells in a
6666			// table row; if so, offsetWidth/Height are not reliable for use when
6667			// determining if an element has been hidden directly using
6668			// display:none (it is still safe to use offsets if a parent element is
6669			// hidden; don safety goggles and see bug #4512 for more information).
6670			div.style.display = "none";
6671			reliableHiddenOffsetsVal = div.getClientRects().length === 0;
6672			if ( reliableHiddenOffsetsVal ) {
6673				div.style.display = "";
6674				div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6675				div.childNodes[ 0 ].style.borderCollapse = "separate";
6676				contents = div.getElementsByTagName( "td" );
6677				contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
6678				reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6679				if ( reliableHiddenOffsetsVal ) {
6680					contents[ 0 ].style.display = "";
6681					contents[ 1 ].style.display = "none";
6682					reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6683				}
6684			}
6685
6686			// Teardown
6687			documentElement.removeChild( container );
6688		}
6689
6690	} )();
6691
6692
6693	var getStyles, curCSS,
6694		rposition = /^(top|right|bottom|left)$/;
6695
6696	if ( window.getComputedStyle ) {
6697		getStyles = function( elem ) {
6698
6699			// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6700			// IE throws on elements created in popups
6701			// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6702			var view = elem.ownerDocument.defaultView;
6703
6704			if ( !view || !view.opener ) {
6705				view = window;
6706			}
6707
6708			return view.getComputedStyle( elem );
6709		};
6710
6711		curCSS = function( elem, name, computed ) {
6712			var width, minWidth, maxWidth, ret,
6713				style = elem.style;
6714
6715			computed = computed || getStyles( elem );
6716
6717			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
6718			ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6719
6720			// Support: Opera 12.1x only
6721			// Fall back to style even without computed
6722			// computed is undefined for elems on document fragments
6723			if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
6724				ret = jQuery.style( elem, name );
6725			}
6726
6727			if ( computed ) {
6728
6729				// A tribute to the "awesome hack by Dean Edwards"
6730				// Chrome < 17 and Safari 5.0 uses "computed value"
6731				// instead of "used value" for margin-right
6732				// Safari 5.1.7 (at least) returns percentage for a larger set of values,
6733				// but width seems to be reliably pixels
6734				// this is against the CSSOM draft spec:
6735				// http://dev.w3.org/csswg/cssom/#resolved-values
6736				if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6737
6738					// Remember the original values
6739					width = style.width;
6740					minWidth = style.minWidth;
6741					maxWidth = style.maxWidth;
6742
6743					// Put in the new values to get a computed value out
6744					style.minWidth = style.maxWidth = style.width = ret;
6745					ret = computed.width;
6746
6747					// Revert the changed values
6748					style.width = width;
6749					style.minWidth = minWidth;
6750					style.maxWidth = maxWidth;
6751				}
6752			}
6753
vendor: 4,280 bytes, lines 6754-6916
6754			// Support: IE
6755			// IE returns zIndex value as an integer.
6756			return ret === undefined ?
6757				ret :
6758				ret + "";
6759		};
6760	} else if ( documentElement.currentStyle ) {
6761		getStyles = function( elem ) {
6762			return elem.currentStyle;
6763		};
6764
6765		curCSS = function( elem, name, computed ) {
6766			var left, rs, rsLeft, ret,
6767				style = elem.style;
6768
6769			computed = computed || getStyles( elem );
6770			ret = computed ? computed[ name ] : undefined;
6771
6772			// Avoid setting ret to empty string here
6773			// so we don't default to auto
6774			if ( ret == null && style && style[ name ] ) {
6775				ret = style[ name ];
6776			}
6777
6778			// From the awesome hack by Dean Edwards
6779			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6780
6781			// If we're not dealing with a regular pixel number
6782			// but a number that has a weird ending, we need to convert it to pixels
6783			// but not position css attributes, as those are
6784			// proportional to the parent element instead
6785			// and we can't measure the parent instead because it
6786			// might trigger a "stacking dolls" problem
6787			if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6788
6789				// Remember the original values
6790				left = style.left;
6791				rs = elem.runtimeStyle;
6792				rsLeft = rs && rs.left;
6793
6794				// Put in the new values to get a computed value out
6795				if ( rsLeft ) {
6796					rs.left = elem.currentStyle.left;
6797				}
6798				style.left = name === "fontSize" ? "1em" : ret;
6799				ret = style.pixelLeft + "px";
6800
6801				// Revert the changed values
6802				style.left = left;
6803				if ( rsLeft ) {
6804					rs.left = rsLeft;
6805				}
6806			}
6807
6808			// Support: IE
6809			// IE returns zIndex value as an integer.
6810			return ret === undefined ?
6811				ret :
6812				ret + "" || "auto";
6813		};
6814	}
6815
6816
6817
6818
6819	function addGetHookIf( conditionFn, hookFn ) {
6820
6821		// Define the hook, we'll check on the first run if it's really needed.
6822		return {
6823			get: function() {
6824				if ( conditionFn() ) {
6825
6826					// Hook not needed (or it's not possible to use it due
6827					// to missing dependency), remove it.
6828					delete this.get;
6829					return;
6830				}
6831
6832				// Hook needed; redefine it so that the support test is not executed again.
6833				return ( this.get = hookFn ).apply( this, arguments );
6834			}
6835		};
6836	}
6837
6838
6839	var
6840
6841		ralpha = /alpha\([^)]*\)/i,
6842		ropacity = /opacity\s*=\s*([^)]*)/i,
6843
6844		// swappable if display is none or starts with table except
6845		// "table", "table-cell", or "table-caption"
6846		// see here for display values:
6847		// https://developer.mozilla.org/en-US/docs/CSS/display
6848		rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6849		rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6850
6851		cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6852		cssNormalTransform = {
6853			letterSpacing: "0",
6854			fontWeight: "400"
6855		},
6856
6857		cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6858		emptyStyle = document.createElement( "div" ).style;
6859
6860
6861// return a css property mapped to a potentially vendor prefixed property
6862	function vendorPropName( name ) {
6863
6864		// shortcut for names that are not vendor prefixed
6865		if ( name in emptyStyle ) {
6866			return name;
6867		}
6868
6869		// check for vendor prefixed names
6870		var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
6871			i = cssPrefixes.length;
6872
6873		while ( i-- ) {
6874			name = cssPrefixes[ i ] + capName;
6875			if ( name in emptyStyle ) {
6876				return name;
6877			}
6878		}
6879	}
6880
6881	function showHide( elements, show ) {
6882		var display, elem, hidden,
6883			values = [],
6884			index = 0,
6885			length = elements.length;
6886
6887		for ( ; index < length; index++ ) {
6888			elem = elements[ index ];
6889			if ( !elem.style ) {
6890				continue;
6891			}
6892
6893			values[ index ] = jQuery._data( elem, "olddisplay" );
6894			display = elem.style.display;
6895			if ( show ) {
6896
6897				// Reset the inline display of this element to learn if it is
6898				// being hidden by cascaded rules or not
6899				if ( !values[ index ] && display === "none" ) {
6900					elem.style.display = "";
6901				}
6902
6903				// Set elements which have been overridden with display: none
6904				// in a stylesheet to whatever the default browser style is
6905				// for such an element
6906				if ( elem.style.display === "" && isHidden( elem ) ) {
6907					values[ index ] =
6908						jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
6909				}
6910			} else {
6911				hidden = isHidden( elem );
6912
6913				if ( display && display !== "none" || !hidden ) {
6914					jQuery._data(
6915						elem,
6916						"olddisplay",
vendor: 6,217 bytes, lines 6917-7128
6917						hidden ? display : jQuery.css( elem, "display" )
6918					);
6919				}
6920			}
6921		}
6922
6923		// Set the display of most of the elements in a second loop
6924		// to avoid the constant reflow
6925		for ( index = 0; index < length; index++ ) {
6926			elem = elements[ index ];
6927			if ( !elem.style ) {
6928				continue;
6929			}
6930			if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6931				elem.style.display = show ? values[ index ] || "" : "none";
6932			}
6933		}
6934
6935		return elements;
6936	}
6937
6938	function setPositiveNumber( elem, value, subtract ) {
6939		var matches = rnumsplit.exec( value );
6940		return matches ?
6941
6942			// Guard against undefined "subtract", e.g., when used as in cssHooks
6943			Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6944			value;
6945	}
6946
6947	function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6948		var i = extra === ( isBorderBox ? "border" : "content" ) ?
6949
6950				// If we already have the right measurement, avoid augmentation
6951				4 :
6952
6953				// Otherwise initialize for horizontal or vertical properties
6954				name === "width" ? 1 : 0,
6955
6956			val = 0;
6957
6958		for ( ; i < 4; i += 2 ) {
6959
6960			// both box models exclude margin, so add it if we want it
6961			if ( extra === "margin" ) {
6962				val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6963			}
6964
6965			if ( isBorderBox ) {
6966
6967				// border-box includes padding, so remove it if we want content
6968				if ( extra === "content" ) {
6969					val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6970				}
6971
6972				// at this point, extra isn't border nor margin, so remove border
6973				if ( extra !== "margin" ) {
6974					val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6975				}
6976			} else {
6977
6978				// at this point, extra isn't content, so add padding
6979				val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6980
6981				// at this point, extra isn't content nor padding, so add border
6982				if ( extra !== "padding" ) {
6983					val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6984				}
6985			}
6986		}
6987
6988		return val;
6989	}
6990
6991	function getWidthOrHeight( elem, name, extra ) {
6992
6993		// Start with offset property, which is equivalent to the border-box value
6994		var valueIsBorderBox = true,
6995			val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6996			styles = getStyles( elem ),
6997			isBorderBox = support.boxSizing &&
6998				jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6999
7000		// some non-html elements return undefined for offsetWidth, so check for null/undefined
7001		// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
7002		// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
7003		if ( val <= 0 || val == null ) {
7004
7005			// Fall back to computed then uncomputed css if necessary
7006			val = curCSS( elem, name, styles );
7007			if ( val < 0 || val == null ) {
7008				val = elem.style[ name ];
7009			}
7010
7011			// Computed unit is not pixels. Stop here and return.
7012			if ( rnumnonpx.test( val ) ) {
7013				return val;
7014			}
7015
7016			// we need the check for style in case a browser which returns unreliable values
7017			// for getComputedStyle silently falls back to the reliable elem.style
7018			valueIsBorderBox = isBorderBox &&
7019				( support.boxSizingReliable() || val === elem.style[ name ] );
7020
7021			// Normalize "", auto, and prepare for extra
7022			val = parseFloat( val ) || 0;
7023		}
7024
7025		// use the active box-sizing model to add/subtract irrelevant styles
7026		return ( val +
7027			augmentWidthOrHeight(
7028				elem,
7029				name,
7030				extra || ( isBorderBox ? "border" : "content" ),
7031				valueIsBorderBox,
7032				styles
7033			)
7034		) + "px";
7035	}
7036
7037	jQuery.extend( {
7038
7039		// Add in style property hooks for overriding the default
7040		// behavior of getting and setting a style property
7041		cssHooks: {
7042			opacity: {
7043				get: function( elem, computed ) {
7044					if ( computed ) {
7045
7046						// We should always get a number back from opacity
7047						var ret = curCSS( elem, "opacity" );
7048						return ret === "" ? "1" : ret;
7049					}
7050				}
7051			}
7052		},
7053
7054		// Don't automatically add "px" to these possibly-unitless properties
7055		cssNumber: {
7056			"animationIterationCount": true,
7057			"columnCount": true,
7058			"fillOpacity": true,
7059			"flexGrow": true,
7060			"flexShrink": true,
7061			"fontWeight": true,
7062			"lineHeight": true,
7063			"opacity": true,
7064			"order": true,
7065			"orphans": true,
7066			"widows": true,
7067			"zIndex": true,
7068			"zoom": true
7069		},
7070
7071		// Add in properties whose names you wish to fix before
7072		// setting or getting the value
7073		cssProps: {
7074
7075			// normalize float css property
7076			"float": support.cssFloat ? "cssFloat" : "styleFloat"
7077		},
7078
7079		// Get and set the style property on a DOM Node
7080		style: function( elem, name, value, extra ) {
7081
7082			// Don't set styles on text and comment nodes
7083			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7084				return;
7085			}
7086
7087			// Make sure that we're working with the right name
7088			var ret, type, hooks,
7089				origName = jQuery.camelCase( name ),
7090				style = elem.style;
7091
7092			name = jQuery.cssProps[ origName ] ||
7093				( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7094
7095			// gets hook for the prefixed version
7096			// followed by the unprefixed version
7097			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7098
7099			// Check if we're setting a value
7100			if ( value !== undefined ) {
7101				type = typeof value;
7102
7103				// Convert "+=" or "-=" to relative numbers (#7345)
7104				if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7105					value = adjustCSS( elem, name, ret );
7106
7107					// Fixes bug #9237
7108					type = "number";
7109				}
7110
7111				// Make sure that null and NaN values aren't set. See: #7116
7112				if ( value == null || value !== value ) {
7113					return;
7114				}
7115
7116				// If a number was passed in, add the unit (except for certain CSS properties)
7117				if ( type === "number" ) {
7118					value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7119				}
7120
7121				// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
7122				// but it would mean to define eight
7123				// (for every problematic property) identical functions
7124				if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7125					style[ name ] = "inherit";
7126				}
7127
7128				// If a hook was provided, use that value, otherwise just set the specified value
vendor: 4,706 bytes, lines 7129-7284
7129				if ( !hooks || !( "set" in hooks ) ||
7130					( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7131
7132					// Support: IE
7133					// Swallow errors from 'invalid' CSS values (#5509)
7134					try {
7135						style[ name ] = value;
7136					} catch ( e ) {}
7137				}
7138
7139			} else {
7140
7141				// If a hook was provided get the non-computed value from there
7142				if ( hooks && "get" in hooks &&
7143					( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7144
7145					return ret;
7146				}
7147
7148				// Otherwise just get the value from the style object
7149				return style[ name ];
7150			}
7151		},
7152
7153		css: function( elem, name, extra, styles ) {
7154			var num, val, hooks,
7155				origName = jQuery.camelCase( name );
7156
7157			// Make sure that we're working with the right name
7158			name = jQuery.cssProps[ origName ] ||
7159				( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7160
7161			// gets hook for the prefixed version
7162			// followed by the unprefixed version
7163			hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7164
7165			// If a hook was provided get the computed value from there
7166			if ( hooks && "get" in hooks ) {
7167				val = hooks.get( elem, true, extra );
7168			}
7169
7170			// Otherwise, if a way to get the computed value exists, use that
7171			if ( val === undefined ) {
7172				val = curCSS( elem, name, styles );
7173			}
7174
7175			//convert "normal" to computed value
7176			if ( val === "normal" && name in cssNormalTransform ) {
7177				val = cssNormalTransform[ name ];
7178			}
7179
7180			// Return, converting to number if forced or a qualifier was provided and val looks numeric
7181			if ( extra === "" || extra ) {
7182				num = parseFloat( val );
7183				return extra === true || isFinite( num ) ? num || 0 : val;
7184			}
7185			return val;
7186		}
7187	} );
7188
7189	jQuery.each( [ "height", "width" ], function( i, name ) {
7190		jQuery.cssHooks[ name ] = {
7191			get: function( elem, computed, extra ) {
7192				if ( computed ) {
7193
7194					// certain elements can have dimension info if we invisibly show them
7195					// however, it must have a current display style that would benefit from this
7196					return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7197					elem.offsetWidth === 0 ?
7198						swap( elem, cssShow, function() {
7199							return getWidthOrHeight( elem, name, extra );
7200						} ) :
7201						getWidthOrHeight( elem, name, extra );
7202				}
7203			},
7204
7205			set: function( elem, value, extra ) {
7206				var styles = extra && getStyles( elem );
7207				return setPositiveNumber( elem, value, extra ?
7208					augmentWidthOrHeight(
7209						elem,
7210						name,
7211						extra,
7212						support.boxSizing &&
7213						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7214						styles
7215					) : 0
7216				);
7217			}
7218		};
7219	} );
7220
7221	if ( !support.opacity ) {
7222		jQuery.cssHooks.opacity = {
7223			get: function( elem, computed ) {
7224
7225				// IE uses filters for opacity
7226				return ropacity.test( ( computed && elem.currentStyle ?
7227					elem.currentStyle.filter :
7228					elem.style.filter ) || "" ) ?
7229					( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7230					computed ? "1" : "";
7231			},
7232
7233			set: function( elem, value ) {
7234				var style = elem.style,
7235					currentStyle = elem.currentStyle,
7236					opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7237					filter = currentStyle && currentStyle.filter || style.filter || "";
7238
7239				// IE has trouble with opacity if it does not have layout
7240				// Force it by setting the zoom level
7241				style.zoom = 1;
7242
7243				// if setting opacity to 1, and no other filters exist -
7244				// attempt to remove filter attribute #6652
7245				// if value === "", then remove inline opacity #12685
7246				if ( ( value >= 1 || value === "" ) &&
7247					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7248					style.removeAttribute ) {
7249
7250					// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7251					// if "filter:" is present at all, clearType is disabled, we want to avoid this
7252					// style.removeAttribute is IE Only, but so apparently is this code path...
7253					style.removeAttribute( "filter" );
7254
7255					// if there is no filter style applied in a css rule
7256					// or unset inline opacity, we are done
7257					if ( value === "" || currentStyle && !currentStyle.filter ) {
7258						return;
7259					}
7260				}
7261
7262				// otherwise, set new filter values
7263				style.filter = ralpha.test( filter ) ?
7264					filter.replace( ralpha, opacity ) :
7265					filter + " " + opacity;
7266			}
7267		};
7268	}
7269
7270	jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
7271		function( elem, computed ) {
7272			if ( computed ) {
7273				return swap( elem, { "display": "inline-block" },
7274					curCSS, [ elem, "marginRight" ] );
7275			}
7276		}
7277	);
7278
7279	jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7280		function( elem, computed ) {
7281			if ( computed ) {
7282				return (
7283					parseFloat( curCSS( elem, "marginLeft" ) ) ||
7284
vendor: 4,203 bytes, lines 7285-7445
7285					// Support: IE<=11+
7286					// Running getBoundingClientRect on a disconnected node in IE throws an error
7287					// Support: IE8 only
7288					// getClientRects() errors on disconnected elems
7289					( jQuery.contains( elem.ownerDocument, elem ) ?
7290							elem.getBoundingClientRect().left -
7291							swap( elem, { marginLeft: 0 }, function() {
7292								return elem.getBoundingClientRect().left;
7293							} ) :
7294							0
7295					)
7296				) + "px";
7297			}
7298		}
7299	);
7300
7301// These hooks are used by animate to expand properties
7302	jQuery.each( {
7303		margin: "",
7304		padding: "",
7305		border: "Width"
7306	}, function( prefix, suffix ) {
7307		jQuery.cssHooks[ prefix + suffix ] = {
7308			expand: function( value ) {
7309				var i = 0,
7310					expanded = {},
7311
7312					// assumes a single number if not a string
7313					parts = typeof value === "string" ? value.split( " " ) : [ value ];
7314
7315				for ( ; i < 4; i++ ) {
7316					expanded[ prefix + cssExpand[ i ] + suffix ] =
7317						parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7318				}
7319
7320				return expanded;
7321			}
7322		};
7323
7324		if ( !rmargin.test( prefix ) ) {
7325			jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7326		}
7327	} );
7328
7329	jQuery.fn.extend( {
7330		css: function( name, value ) {
7331			return access( this, function( elem, name, value ) {
7332				var styles, len,
7333					map = {},
7334					i = 0;
7335
7336				if ( jQuery.isArray( name ) ) {
7337					styles = getStyles( elem );
7338					len = name.length;
7339
7340					for ( ; i < len; i++ ) {
7341						map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7342					}
7343
7344					return map;
7345				}
7346
7347				return value !== undefined ?
7348					jQuery.style( elem, name, value ) :
7349					jQuery.css( elem, name );
7350			}, name, value, arguments.length > 1 );
7351		},
7352		show: function() {
7353			return showHide( this, true );
7354		},
7355		hide: function() {
7356			return showHide( this );
7357		},
7358		toggle: function( state ) {
7359			if ( typeof state === "boolean" ) {
7360				return state ? this.show() : this.hide();
7361			}
7362
7363			return this.each( function() {
7364				if ( isHidden( this ) ) {
7365					jQuery( this ).show();
7366				} else {
7367					jQuery( this ).hide();
7368				}
7369			} );
7370		}
7371	} );
7372
7373
7374	function Tween( elem, options, prop, end, easing ) {
7375		return new Tween.prototype.init( elem, options, prop, end, easing );
7376	}
7377	jQuery.Tween = Tween;
7378
7379	Tween.prototype = {
7380		constructor: Tween,
7381		init: function( elem, options, prop, end, easing, unit ) {
7382			this.elem = elem;
7383			this.prop = prop;
7384			this.easing = easing || jQuery.easing._default;
7385			this.options = options;
7386			this.start = this.now = this.cur();
7387			this.end = end;
7388			this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7389		},
7390		cur: function() {
7391			var hooks = Tween.propHooks[ this.prop ];
7392
7393			return hooks && hooks.get ?
7394				hooks.get( this ) :
7395				Tween.propHooks._default.get( this );
7396		},
7397		run: function( percent ) {
7398			var eased,
7399				hooks = Tween.propHooks[ this.prop ];
7400
7401			if ( this.options.duration ) {
7402				this.pos = eased = jQuery.easing[ this.easing ](
7403					percent, this.options.duration * percent, 0, 1, this.options.duration
7404				);
7405			} else {
7406				this.pos = eased = percent;
7407			}
7408			this.now = ( this.end - this.start ) * eased + this.start;
7409
7410			if ( this.options.step ) {
7411				this.options.step.call( this.elem, this.now, this );
7412			}
7413
7414			if ( hooks && hooks.set ) {
7415				hooks.set( this );
7416			} else {
7417				Tween.propHooks._default.set( this );
7418			}
7419			return this;
7420		}
7421	};
7422
7423	Tween.prototype.init.prototype = Tween.prototype;
7424
7425	Tween.propHooks = {
7426		_default: {
7427			get: function( tween ) {
7428				var result;
7429
7430				// Use a property on the element directly when it is not a DOM element,
7431				// or when there is no matching style property that exists.
7432				if ( tween.elem.nodeType !== 1 ||
7433					tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7434					return tween.elem[ tween.prop ];
7435				}
7436
7437				// passing an empty string as a 3rd parameter to .css will automatically
7438				// attempt a parseFloat and fallback to a string if the parse fails
7439				// so, simple values such as "10px" are parsed to Float.
7440				// complex values such as "rotate(1rad)" are returned as is.
7441				result = jQuery.css( tween.elem, tween.prop, "" );
7442
7443				// Empty strings, null, undefined and "auto" are converted to 0.
7444				return !result || result === "auto" ? 0 : result;
7445			},
vendor: 6,412 bytes, lines 7446-7680
7446			set: function( tween ) {
7447
7448				// use step hook for back compat - use cssHook if its there - use .style if its
7449				// available and use plain properties where available
7450				if ( jQuery.fx.step[ tween.prop ] ) {
7451					jQuery.fx.step[ tween.prop ]( tween );
7452				} else if ( tween.elem.nodeType === 1 &&
7453					( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
7454						jQuery.cssHooks[ tween.prop ] ) ) {
7455					jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7456				} else {
7457					tween.elem[ tween.prop ] = tween.now;
7458				}
7459			}
7460		}
7461	};
7462
7463// Support: IE <=9
7464// Panic based approach to setting things on disconnected nodes
7465
7466	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7467		set: function( tween ) {
7468			if ( tween.elem.nodeType && tween.elem.parentNode ) {
7469				tween.elem[ tween.prop ] = tween.now;
7470			}
7471		}
7472	};
7473
7474	jQuery.easing = {
7475		linear: function( p ) {
7476			return p;
7477		},
7478		swing: function( p ) {
7479			return 0.5 - Math.cos( p * Math.PI ) / 2;
7480		},
7481		_default: "swing"
7482	};
7483
7484	jQuery.fx = Tween.prototype.init;
7485
7486// Back Compat <1.8 extension point
7487	jQuery.fx.step = {};
7488
7489
7490
7491
7492	var
7493		fxNow, timerId,
7494		rfxtypes = /^(?:toggle|show|hide)$/,
7495		rrun = /queueHooks$/;
7496
7497// Animations created synchronously will run synchronously
7498	function createFxNow() {
7499		window.setTimeout( function() {
7500			fxNow = undefined;
7501		} );
7502		return ( fxNow = jQuery.now() );
7503	}
7504
7505// Generate parameters to create a standard animation
7506	function genFx( type, includeWidth ) {
7507		var which,
7508			attrs = { height: type },
7509			i = 0;
7510
7511		// if we include width, step value is 1 to do all cssExpand values,
7512		// if we don't include width, step value is 2 to skip over Left and Right
7513		includeWidth = includeWidth ? 1 : 0;
7514		for ( ; i < 4 ; i += 2 - includeWidth ) {
7515			which = cssExpand[ i ];
7516			attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7517		}
7518
7519		if ( includeWidth ) {
7520			attrs.opacity = attrs.width = type;
7521		}
7522
7523		return attrs;
7524	}
7525
7526	function createTween( value, prop, animation ) {
7527		var tween,
7528			collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7529			index = 0,
7530			length = collection.length;
7531		for ( ; index < length; index++ ) {
7532			if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7533
7534				// we're done with this property
7535				return tween;
7536			}
7537		}
7538	}
7539
7540	function defaultPrefilter( elem, props, opts ) {
7541		/* jshint validthis: true */
7542		var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
7543			anim = this,
7544			orig = {},
7545			style = elem.style,
7546			hidden = elem.nodeType && isHidden( elem ),
7547			dataShow = jQuery._data( elem, "fxshow" );
7548
7549		// handle queue: false promises
7550		if ( !opts.queue ) {
7551			hooks = jQuery._queueHooks( elem, "fx" );
7552			if ( hooks.unqueued == null ) {
7553				hooks.unqueued = 0;
7554				oldfire = hooks.empty.fire;
7555				hooks.empty.fire = function() {
7556					if ( !hooks.unqueued ) {
7557						oldfire();
7558					}
7559				};
7560			}
7561			hooks.unqueued++;
7562
7563			anim.always( function() {
7564
7565				// doing this makes sure that the complete handler will be called
7566				// before this completes
7567				anim.always( function() {
7568					hooks.unqueued--;
7569					if ( !jQuery.queue( elem, "fx" ).length ) {
7570						hooks.empty.fire();
7571					}
7572				} );
7573			} );
7574		}
7575
7576		// height/width overflow pass
7577		if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7578
7579			// Make sure that nothing sneaks out
7580			// Record all 3 overflow attributes because IE does not
7581			// change the overflow attribute when overflowX and
7582			// overflowY are set to the same value
7583			opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7584
7585			// Set display property to inline-block for height/width
7586			// animations on inline elements that are having width/height animated
7587			display = jQuery.css( elem, "display" );
7588
7589			// Test default display if display is currently "none"
7590			checkDisplay = display === "none" ?
7591				jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
7592
7593			if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
7594
7595				// inline-level elements accept inline-block;
7596				// block-level elements need to be inline with layout
7597				if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
7598					style.display = "inline-block";
7599				} else {
7600					style.zoom = 1;
7601				}
7602			}
7603		}
7604
7605		if ( opts.overflow ) {
7606			style.overflow = "hidden";
7607			if ( !support.shrinkWrapBlocks() ) {
7608				anim.always( function() {
7609					style.overflow = opts.overflow[ 0 ];
7610					style.overflowX = opts.overflow[ 1 ];
7611					style.overflowY = opts.overflow[ 2 ];
7612				} );
7613			}
7614		}
7615
7616		// show/hide pass
7617		for ( prop in props ) {
7618			value = props[ prop ];
7619			if ( rfxtypes.exec( value ) ) {
7620				delete props[ prop ];
7621				toggle = toggle || value === "toggle";
7622				if ( value === ( hidden ? "hide" : "show" ) ) {
7623
7624					// If there is dataShow left over from a stopped hide or show
7625					// and we are going to proceed with show, we should pretend to be hidden
7626					if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7627						hidden = true;
7628					} else {
7629						continue;
7630					}
7631				}
7632				orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7633
7634				// Any non-fx value stops us from restoring the original display value
7635			} else {
7636				display = undefined;
7637			}
7638		}
7639
7640		if ( !jQuery.isEmptyObject( orig ) ) {
7641			if ( dataShow ) {
7642				if ( "hidden" in dataShow ) {
7643					hidden = dataShow.hidden;
7644				}
7645			} else {
7646				dataShow = jQuery._data( elem, "fxshow", {} );
7647			}
7648
7649			// store state if its toggle - enables .stop().toggle() to "reverse"
7650			if ( toggle ) {
7651				dataShow.hidden = !hidden;
7652			}
7653			if ( hidden ) {
7654				jQuery( elem ).show();
7655			} else {
7656				anim.done( function() {
7657					jQuery( elem ).hide();
7658				} );
7659			}
7660			anim.done( function() {
7661				var prop;
7662				jQuery._removeData( elem, "fxshow" );
7663				for ( prop in orig ) {
7664					jQuery.style( elem, prop, orig[ prop ] );
7665				}
7666			} );
7667			for ( prop in orig ) {
7668				tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7669
7670				if ( !( prop in dataShow ) ) {
7671					dataShow[ prop ] = tween.start;
7672					if ( hidden ) {
7673						tween.end = tween.start;
7674						tween.start = prop === "width" || prop === "height" ? 1 : 0;
7675					}
7676				}
7677			}
7678
7679			// If this is a noop like .hide().hide(), restore an overwritten display value
7680		} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : dis
vendor: 8,001 bytes, lines 7680-7978
7680play ) === "inline" ) {
7681			style.display = display;
7682		}
7683	}
7684
7685	function propFilter( props, specialEasing ) {
7686		var index, name, easing, value, hooks;
7687
7688		// camelCase, specialEasing and expand cssHook pass
7689		for ( index in props ) {
7690			name = jQuery.camelCase( index );
7691			easing = specialEasing[ name ];
7692			value = props[ index ];
7693			if ( jQuery.isArray( value ) ) {
7694				easing = value[ 1 ];
7695				value = props[ index ] = value[ 0 ];
7696			}
7697
7698			if ( index !== name ) {
7699				props[ name ] = value;
7700				delete props[ index ];
7701			}
7702
7703			hooks = jQuery.cssHooks[ name ];
7704			if ( hooks && "expand" in hooks ) {
7705				value = hooks.expand( value );
7706				delete props[ name ];
7707
7708				// not quite $.extend, this wont overwrite keys already present.
7709				// also - reusing 'index' from above because we have the correct "name"
7710				for ( index in value ) {
7711					if ( !( index in props ) ) {
7712						props[ index ] = value[ index ];
7713						specialEasing[ index ] = easing;
7714					}
7715				}
7716			} else {
7717				specialEasing[ name ] = easing;
7718			}
7719		}
7720	}
7721
7722	function Animation( elem, properties, options ) {
7723		var result,
7724			stopped,
7725			index = 0,
7726			length = Animation.prefilters.length,
7727			deferred = jQuery.Deferred().always( function() {
7728
7729				// don't match elem in the :animated selector
7730				delete tick.elem;
7731			} ),
7732			tick = function() {
7733				if ( stopped ) {
7734					return false;
7735				}
7736				var currentTime = fxNow || createFxNow(),
7737					remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7738
7739					// Support: Android 2.3
7740					// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7741					temp = remaining / animation.duration || 0,
7742					percent = 1 - temp,
7743					index = 0,
7744					length = animation.tweens.length;
7745
7746				for ( ; index < length ; index++ ) {
7747					animation.tweens[ index ].run( percent );
7748				}
7749
7750				deferred.notifyWith( elem, [ animation, percent, remaining ] );
7751
7752				if ( percent < 1 && length ) {
7753					return remaining;
7754				} else {
7755					deferred.resolveWith( elem, [ animation ] );
7756					return false;
7757				}
7758			},
7759			animation = deferred.promise( {
7760				elem: elem,
7761				props: jQuery.extend( {}, properties ),
7762				opts: jQuery.extend( true, {
7763					specialEasing: {},
7764					easing: jQuery.easing._default
7765				}, options ),
7766				originalProperties: properties,
7767				originalOptions: options,
7768				startTime: fxNow || createFxNow(),
7769				duration: options.duration,
7770				tweens: [],
7771				createTween: function( prop, end ) {
7772					var tween = jQuery.Tween( elem, animation.opts, prop, end,
7773						animation.opts.specialEasing[ prop ] || animation.opts.easing );
7774					animation.tweens.push( tween );
7775					return tween;
7776				},
7777				stop: function( gotoEnd ) {
7778					var index = 0,
7779
7780						// if we are going to the end, we want to run all the tweens
7781						// otherwise we skip this part
7782						length = gotoEnd ? animation.tweens.length : 0;
7783					if ( stopped ) {
7784						return this;
7785					}
7786					stopped = true;
7787					for ( ; index < length ; index++ ) {
7788						animation.tweens[ index ].run( 1 );
7789					}
7790
7791					// resolve when we played the last frame
7792					// otherwise, reject
7793					if ( gotoEnd ) {
7794						deferred.notifyWith( elem, [ animation, 1, 0 ] );
7795						deferred.resolveWith( elem, [ animation, gotoEnd ] );
7796					} else {
7797						deferred.rejectWith( elem, [ animation, gotoEnd ] );
7798					}
7799					return this;
7800				}
7801			} ),
7802			props = animation.props;
7803
7804		propFilter( props, animation.opts.specialEasing );
7805
7806		for ( ; index < length ; index++ ) {
7807			result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7808			if ( result ) {
7809				if ( jQuery.isFunction( result.stop ) ) {
7810					jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7811						jQuery.proxy( result.stop, result );
7812				}
7813				return result;
7814			}
7815		}
7816
7817		jQuery.map( props, createTween, animation );
7818
7819		if ( jQuery.isFunction( animation.opts.start ) ) {
7820			animation.opts.start.call( elem, animation );
7821		}
7822
7823		jQuery.fx.timer(
7824			jQuery.extend( tick, {
7825				elem: elem,
7826				anim: animation,
7827				queue: animation.opts.queue
7828			} )
7829		);
7830
7831		// attach callbacks from options
7832		return animation.progress( animation.opts.progress )
7833			.done( animation.opts.done, animation.opts.complete )
7834			.fail( animation.opts.fail )
7835			.always( animation.opts.always );
7836	}
7837
7838	jQuery.Animation = jQuery.extend( Animation, {
7839
7840		tweeners: {
7841			"*": [ function( prop, value ) {
7842				var tween = this.createTween( prop, value );
7843				adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7844				return tween;
7845			} ]
7846		},
7847
7848		tweener: function( props, callback ) {
7849			if ( jQuery.isFunction( props ) ) {
7850				callback = props;
7851				props = [ "*" ];
7852			} else {
7853				props = props.match( rnotwhite );
7854			}
7855
7856			var prop,
7857				index = 0,
7858				length = props.length;
7859
7860			for ( ; index < length ; index++ ) {
7861				prop = props[ index ];
7862				Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7863				Animation.tweeners[ prop ].unshift( callback );
7864			}
7865		},
7866
7867		prefilters: [ defaultPrefilter ],
7868
7869		prefilter: function( callback, prepend ) {
7870			if ( prepend ) {
7871				Animation.prefilters.unshift( callback );
7872			} else {
7873				Animation.prefilters.push( callback );
7874			}
7875		}
7876	} );
7877
7878	jQuery.speed = function( speed, easing, fn ) {
7879		var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7880			complete: fn || !fn && easing ||
7881				jQuery.isFunction( speed ) && speed,
7882			duration: speed,
7883			easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7884		};
7885
7886		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7887			opt.duration in jQuery.fx.speeds ?
7888				jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7889
7890		// normalize opt.queue - true/undefined/null -> "fx"
7891		if ( opt.queue == null || opt.queue === true ) {
7892			opt.queue = "fx";
7893		}
7894
7895		// Queueing
7896		opt.old = opt.complete;
7897
7898		opt.complete = function() {
7899			if ( jQuery.isFunction( opt.old ) ) {
7900				opt.old.call( this );
7901			}
7902
7903			if ( opt.queue ) {
7904				jQuery.dequeue( this, opt.queue );
7905			}
7906		};
7907
7908		return opt;
7909	};
7910
7911	jQuery.fn.extend( {
7912		fadeTo: function( speed, to, easing, callback ) {
7913
7914			// show any hidden elements after setting opacity to 0
7915			return this.filter( isHidden ).css( "opacity", 0 ).show()
7916
7917				// animate to the value specified
7918				.end().animate( { opacity: to }, speed, easing, callback );
7919		},
7920		animate: function( prop, speed, easing, callback ) {
7921			var empty = jQuery.isEmptyObject( prop ),
7922				optall = jQuery.speed( speed, easing, callback ),
7923				doAnimation = function() {
7924
7925					// Operate on a copy of prop so per-property easing won't be lost
7926					var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7927
7928					// Empty animations, or finishing resolves immediately
7929					if ( empty || jQuery._data( this, "finish" ) ) {
7930						anim.stop( true );
7931					}
7932				};
7933			doAnimation.finish = doAnimation;
7934
7935			return empty || optall.queue === false ?
7936				this.each( doAnimation ) :
7937				this.queue( optall.queue, doAnimation );
7938		},
7939		stop: function( type, clearQueue, gotoEnd ) {
7940			var stopQueue = function( hooks ) {
7941				var stop = hooks.stop;
7942				delete hooks.stop;
7943				stop( gotoEnd );
7944			};
7945
7946			if ( typeof type !== "string" ) {
7947				gotoEnd = clearQueue;
7948				clearQueue = type;
7949				type = undefined;
7950			}
7951			if ( clearQueue && type !== false ) {
7952				this.queue( type || "fx", [] );
7953			}
7954
7955			return this.each( function() {
7956				var dequeue = true,
7957					index = type != null && type + "queueHooks",
7958					timers = jQuery.timers,
7959					data = jQuery._data( this );
7960
7961				if ( index ) {
7962					if ( data[ index ] && data[ index ].stop ) {
7963						stopQueue( data[ index ] );
7964					}
7965				} else {
7966					for ( index in data ) {
7967						if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7968							stopQueue( data[ index ] );
7969						}
7970					}
7971				}
7972
7973				for ( index = timers.length; index--; ) {
7974					if ( timers[ index ].elem === this &&
7975						( type == null || timers[ index ].queue === type ) ) {
7976
7977						timers[ index ].anim.stop( gotoEnd );
7978						dequeue = false;
vendor: 7,136 bytes, lines 7979-8252
7979						timers.splice( index, 1 );
7980					}
7981				}
7982
7983				// start the next in the queue if the last step wasn't forced
7984				// timers currently will call their complete callbacks, which will dequeue
7985				// but only if they were gotoEnd
7986				if ( dequeue || !gotoEnd ) {
7987					jQuery.dequeue( this, type );
7988				}
7989			} );
7990		},
7991		finish: function( type ) {
7992			if ( type !== false ) {
7993				type = type || "fx";
7994			}
7995			return this.each( function() {
7996				var index,
7997					data = jQuery._data( this ),
7998					queue = data[ type + "queue" ],
7999					hooks = data[ type + "queueHooks" ],
8000					timers = jQuery.timers,
8001					length = queue ? queue.length : 0;
8002
8003				// enable finishing flag on private data
8004				data.finish = true;
8005
8006				// empty the queue first
8007				jQuery.queue( this, type, [] );
8008
8009				if ( hooks && hooks.stop ) {
8010					hooks.stop.call( this, true );
8011				}
8012
8013				// look for any active animations, and finish them
8014				for ( index = timers.length; index--; ) {
8015					if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8016						timers[ index ].anim.stop( true );
8017						timers.splice( index, 1 );
8018					}
8019				}
8020
8021				// look for any animations in the old queue and finish them
8022				for ( index = 0; index < length; index++ ) {
8023					if ( queue[ index ] && queue[ index ].finish ) {
8024						queue[ index ].finish.call( this );
8025					}
8026				}
8027
8028				// turn off finishing flag
8029				delete data.finish;
8030			} );
8031		}
8032	} );
8033
8034	jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
8035		var cssFn = jQuery.fn[ name ];
8036		jQuery.fn[ name ] = function( speed, easing, callback ) {
8037			return speed == null || typeof speed === "boolean" ?
8038				cssFn.apply( this, arguments ) :
8039				this.animate( genFx( name, true ), speed, easing, callback );
8040		};
8041	} );
8042
8043// Generate shortcuts for custom animations
8044	jQuery.each( {
8045		slideDown: genFx( "show" ),
8046		slideUp: genFx( "hide" ),
8047		slideToggle: genFx( "toggle" ),
8048		fadeIn: { opacity: "show" },
8049		fadeOut: { opacity: "hide" },
8050		fadeToggle: { opacity: "toggle" }
8051	}, function( name, props ) {
8052		jQuery.fn[ name ] = function( speed, easing, callback ) {
8053			return this.animate( props, speed, easing, callback );
8054		};
8055	} );
8056
8057	jQuery.timers = [];
8058	jQuery.fx.tick = function() {
8059		var timer,
8060			timers = jQuery.timers,
8061			i = 0;
8062
8063		fxNow = jQuery.now();
8064
8065		for ( ; i < timers.length; i++ ) {
8066			timer = timers[ i ];
8067
8068			// Checks the timer has not already been removed
8069			if ( !timer() && timers[ i ] === timer ) {
8070				timers.splice( i--, 1 );
8071			}
8072		}
8073
8074		if ( !timers.length ) {
8075			jQuery.fx.stop();
8076		}
8077		fxNow = undefined;
8078	};
8079
8080	jQuery.fx.timer = function( timer ) {
8081		jQuery.timers.push( timer );
8082		if ( timer() ) {
8083			jQuery.fx.start();
8084		} else {
8085			jQuery.timers.pop();
8086		}
8087	};
8088
8089	jQuery.fx.interval = 13;
8090
8091	jQuery.fx.start = function() {
8092		if ( !timerId ) {
8093			timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
8094		}
8095	};
8096
8097	jQuery.fx.stop = function() {
8098		window.clearInterval( timerId );
8099		timerId = null;
8100	};
8101
8102	jQuery.fx.speeds = {
8103		slow: 600,
8104		fast: 200,
8105
8106		// Default speed
8107		_default: 400
8108	};
8109
8110
8111// Based off of the plugin by Clint Helfers, with permission.
8112// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8113	jQuery.fn.delay = function( time, type ) {
8114		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8115		type = type || "fx";
8116
8117		return this.queue( type, function( next, hooks ) {
8118			var timeout = window.setTimeout( next, time );
8119			hooks.stop = function() {
8120				window.clearTimeout( timeout );
8121			};
8122		} );
8123	};
8124
8125
8126	( function() {
8127		var a,
8128			input = document.createElement( "input" ),
8129			div = document.createElement( "div" ),
8130			select = document.createElement( "select" ),
8131			opt = select.appendChild( document.createElement( "option" ) );
8132
8133		// Setup
8134		div = document.createElement( "div" );
8135		div.setAttribute( "className", "t" );
8136		div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
8137		a = div.getElementsByTagName( "a" )[ 0 ];
8138
8139		// Support: Windows Web Apps (WWA)
8140		// `type` must use .setAttribute for WWA (#14901)
8141		input.setAttribute( "type", "checkbox" );
8142		div.appendChild( input );
8143
8144		a = div.getElementsByTagName( "a" )[ 0 ];
8145
8146		// First batch of tests.
8147		a.style.cssText = "top:1px";
8148
8149		// Test setAttribute on camelCase class.
8150		// If it works, we need attrFixes when doing get/setAttribute (ie6/7)
8151		support.getSetAttribute = div.className !== "t";
8152
8153		// Get the style information from getAttribute
8154		// (IE uses .cssText instead)
8155		support.style = /top/.test( a.getAttribute( "style" ) );
8156
8157		// Make sure that URLs aren't manipulated
8158		// (IE normalizes it by default)
8159		support.hrefNormalized = a.getAttribute( "href" ) === "/a";
8160
8161		// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
8162		support.checkOn = !!input.value;
8163
8164		// Make sure that a selected-by-default option has a working selected property.
8165		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
8166		support.optSelected = opt.selected;
8167
8168		// Tests for enctype support on a form (#6743)
8169		support.enctype = !!document.createElement( "form" ).enctype;
8170
8171		// Make sure that the options inside disabled selects aren't marked as disabled
8172		// (WebKit marks them as disabled)
8173		select.disabled = true;
8174		support.optDisabled = !opt.disabled;
8175
8176		// Support: IE8 only
8177		// Check if we can trust getAttribute("value")
8178		input = document.createElement( "input" );
8179		input.setAttribute( "value", "" );
8180		support.input = input.getAttribute( "value" ) === "";
8181
8182		// Check if an input maintains its value after becoming a radio
8183		input.value = "t";
8184		input.setAttribute( "type", "radio" );
8185		support.radioValue = input.value === "t";
8186	} )();
8187
8188
8189	var rreturn = /\r/g,
8190		rspaces = /[\x20\t\r\n\f]+/g;
8191
8192	jQuery.fn.extend( {
8193		val: function( value ) {
8194			var hooks, ret, isFunction,
8195				elem = this[ 0 ];
8196
8197			if ( !arguments.length ) {
8198				if ( elem ) {
8199					hooks = jQuery.valHooks[ elem.type ] ||
8200						jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8201
8202					if (
8203						hooks &&
8204						"get" in hooks &&
8205						( ret = hooks.get( elem, "value" ) ) !== undefined
8206					) {
8207						return ret;
8208					}
8209
8210					ret = elem.value;
8211
8212					return typeof ret === "string" ?
8213
8214						// handle most common string cases
8215						ret.replace( rreturn, "" ) :
8216
8217						// handle cases where value is null/undef or number
8218						ret == null ? "" : ret;
8219				}
8220
8221				return;
8222			}
8223
8224			isFunction = jQuery.isFunction( value );
8225
8226			return this.each( function( i ) {
8227				var val;
8228
8229				if ( this.nodeType !== 1 ) {
8230					return;
8231				}
8232
8233				if ( isFunction ) {
8234					val = value.call( this, i, jQuery( this ).val() );
8235				} else {
8236					val = value;
8237				}
8238
8239				// Treat null/undefined as ""; convert numbers to string
8240				if ( val == null ) {
8241					val = "";
8242				} else if ( typeof val === "number" ) {
8243					val += "";
8244				} else if ( jQuery.isArray( val ) ) {
8245					val = jQuery.map( val, function( value ) {
8246						return value == null ? "" : value + "";
8247					} );
8248				}
8249
8250				hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8251
8252				// If set returns undefined, fall back to normal setting
vendor: 5,787 bytes, lines 8253-8475
8253				if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8254					this.value = val;
8255				}
8256			} );
8257		}
8258	} );
8259
8260	jQuery.extend( {
8261		valHooks: {
8262			option: {
8263				get: function( elem ) {
8264					var val = jQuery.find.attr( elem, "value" );
8265					return val != null ?
8266						val :
8267
8268						// Support: IE10-11+
8269						// option.text throws exceptions (#14686, #14858)
8270						// Strip and collapse whitespace
8271						// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8272						jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
8273				}
8274			},
8275			select: {
8276				get: function( elem ) {
8277					var value, option,
8278						options = elem.options,
8279						index = elem.selectedIndex,
8280						one = elem.type === "select-one" || index < 0,
8281						values = one ? null : [],
8282						max = one ? index + 1 : options.length,
8283						i = index < 0 ?
8284							max :
8285							one ? index : 0;
8286
8287					// Loop through all the selected options
8288					for ( ; i < max; i++ ) {
8289						option = options[ i ];
8290
8291						// oldIE doesn't update selected after form reset (#2551)
8292						if ( ( option.selected || i === index ) &&
8293
8294							// Don't return options that are disabled or in a disabled optgroup
8295							( support.optDisabled ?
8296								!option.disabled :
8297								option.getAttribute( "disabled" ) === null ) &&
8298							( !option.parentNode.disabled ||
8299								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
8300
8301							// Get the specific value for the option
8302							value = jQuery( option ).val();
8303
8304							// We don't need an array for one selects
8305							if ( one ) {
8306								return value;
8307							}
8308
8309							// Multi-Selects return an array
8310							values.push( value );
8311						}
8312					}
8313
8314					return values;
8315				},
8316
8317				set: function( elem, value ) {
8318					var optionSet, option,
8319						options = elem.options,
8320						values = jQuery.makeArray( value ),
8321						i = options.length;
8322
8323					while ( i-- ) {
8324						option = options[ i ];
8325
8326						if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
8327
8328							// Support: IE6
8329							// When new option element is added to select box we need to
8330							// force reflow of newly added node in order to workaround delay
8331							// of initialization properties
8332							try {
8333								option.selected = optionSet = true;
8334
8335							} catch ( _ ) {
8336
8337								// Will be executed only in IE6
8338								option.scrollHeight;
8339							}
8340
8341						} else {
8342							option.selected = false;
8343						}
8344					}
8345
8346					// Force browsers to behave consistently when non-matching value is set
8347					if ( !optionSet ) {
8348						elem.selectedIndex = -1;
8349					}
8350
8351					return options;
8352				}
8353			}
8354		}
8355	} );
8356
8357// Radios and checkboxes getter/setter
8358	jQuery.each( [ "radio", "checkbox" ], function() {
8359		jQuery.valHooks[ this ] = {
8360			set: function( elem, value ) {
8361				if ( jQuery.isArray( value ) ) {
8362					return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8363				}
8364			}
8365		};
8366		if ( !support.checkOn ) {
8367			jQuery.valHooks[ this ].get = function( elem ) {
8368				return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8369			};
8370		}
8371	} );
8372
8373
8374
8375
8376	var nodeHook, boolHook,
8377		attrHandle = jQuery.expr.attrHandle,
8378		ruseDefault = /^(?:checked|selected)$/i,
8379		getSetAttribute = support.getSetAttribute,
8380		getSetInput = support.input;
8381
8382	jQuery.fn.extend( {
8383		attr: function( name, value ) {
8384			return access( this, jQuery.attr, name, value, arguments.length > 1 );
8385		},
8386
8387		removeAttr: function( name ) {
8388			return this.each( function() {
8389				jQuery.removeAttr( this, name );
8390			} );
8391		}
8392	} );
8393
8394	jQuery.extend( {
8395		attr: function( elem, name, value ) {
8396			var ret, hooks,
8397				nType = elem.nodeType;
8398
8399			// Don't get/set attributes on text, comment and attribute nodes
8400			if ( nType === 3 || nType === 8 || nType === 2 ) {
8401				return;
8402			}
8403
8404			// Fallback to prop when attributes are not supported
8405			if ( typeof elem.getAttribute === "undefined" ) {
8406				return jQuery.prop( elem, name, value );
8407			}
8408
8409			// All attributes are lowercase
8410			// Grab necessary hook if one is defined
8411			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8412				name = name.toLowerCase();
8413				hooks = jQuery.attrHooks[ name ] ||
8414					( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
8415			}
8416
8417			if ( value !== undefined ) {
8418				if ( value === null ) {
8419					jQuery.removeAttr( elem, name );
8420					return;
8421				}
8422
8423				if ( hooks && "set" in hooks &&
8424					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8425					return ret;
8426				}
8427
8428				elem.setAttribute( name, value + "" );
8429				return value;
8430			}
8431
8432			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8433				return ret;
8434			}
8435
8436			ret = jQuery.find.attr( elem, name );
8437
8438			// Non-existent attributes return null, we normalize to undefined
8439			return ret == null ? undefined : ret;
8440		},
8441
8442		attrHooks: {
8443			type: {
8444				set: function( elem, value ) {
8445					if ( !support.radioValue && value === "radio" &&
8446						jQuery.nodeName( elem, "input" ) ) {
8447
8448						// Setting the type on a radio button after the value resets the value in IE8-9
8449						// Reset value to default in case type is set after value during creation
8450						var val = elem.value;
8451						elem.setAttribute( "type", value );
8452						if ( val ) {
8453							elem.value = val;
8454						}
8455						return value;
8456					}
8457				}
8458			}
8459		},
8460
8461		removeAttr: function( elem, value ) {
8462			var name, propName,
8463				i = 0,
8464				attrNames = value && value.match( rnotwhite );
8465
8466			if ( attrNames && elem.nodeType === 1 ) {
8467				while ( ( name = attrNames[ i++ ] ) ) {
8468					propName = jQuery.propFix[ name ] || name;
8469
8470					// Boolean attributes get special treatment (#10870)
8471					if ( jQuery.expr.match.bool.test( name ) ) {
8472
8473						// Set corresponding property to false
8474						if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8475							elem[ propName ] = false;
vendor: 4,518 bytes, lines 8476-8640
8476
8477							// Support: IE<9
8478							// Also clear defaultChecked/defaultSelected (if appropriate)
8479						} else {
8480							elem[ jQuery.camelCase( "default-" + name ) ] =
8481								elem[ propName ] = false;
8482						}
8483
8484						// See #9699 for explanation of this approach (setting first, then removal)
8485					} else {
8486						jQuery.attr( elem, name, "" );
8487					}
8488
8489					elem.removeAttribute( getSetAttribute ? name : propName );
8490				}
8491			}
8492		}
8493	} );
8494
8495// Hooks for boolean attributes
8496	boolHook = {
8497		set: function( elem, value, name ) {
8498			if ( value === false ) {
8499
8500				// Remove boolean attributes when set to false
8501				jQuery.removeAttr( elem, name );
8502			} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8503
8504				// IE<8 needs the *property* name
8505				elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8506
8507			} else {
8508
8509				// Support: IE<9
8510				// Use defaultChecked and defaultSelected for oldIE
8511				elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8512			}
8513			return name;
8514		}
8515	};
8516
8517	jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8518		var getter = attrHandle[ name ] || jQuery.find.attr;
8519
8520		if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8521			attrHandle[ name ] = function( elem, name, isXML ) {
8522				var ret, handle;
8523				if ( !isXML ) {
8524
8525					// Avoid an infinite loop by temporarily removing this function from the getter
8526					handle = attrHandle[ name ];
8527					attrHandle[ name ] = ret;
8528					ret = getter( elem, name, isXML ) != null ?
8529						name.toLowerCase() :
8530						null;
8531					attrHandle[ name ] = handle;
8532				}
8533				return ret;
8534			};
8535		} else {
8536			attrHandle[ name ] = function( elem, name, isXML ) {
8537				if ( !isXML ) {
8538					return elem[ jQuery.camelCase( "default-" + name ) ] ?
8539						name.toLowerCase() :
8540						null;
8541				}
8542			};
8543		}
8544	} );
8545
8546// fix oldIE attroperties
8547	if ( !getSetInput || !getSetAttribute ) {
8548		jQuery.attrHooks.value = {
8549			set: function( elem, value, name ) {
8550				if ( jQuery.nodeName( elem, "input" ) ) {
8551
8552					// Does not return so that setAttribute is also used
8553					elem.defaultValue = value;
8554				} else {
8555
8556					// Use nodeHook if defined (#1954); otherwise setAttribute is fine
8557					return nodeHook && nodeHook.set( elem, value, name );
8558				}
8559			}
8560		};
8561	}
8562
8563// IE6/7 do not support getting/setting some attributes with get/setAttribute
8564	if ( !getSetAttribute ) {
8565
8566		// Use this for any attribute in IE6/7
8567		// This fixes almost every IE6/7 issue
8568		nodeHook = {
8569			set: function( elem, value, name ) {
8570
8571				// Set the existing or create a new attribute node
8572				var ret = elem.getAttributeNode( name );
8573				if ( !ret ) {
8574					elem.setAttributeNode(
8575						( ret = elem.ownerDocument.createAttribute( name ) )
8576					);
8577				}
8578
8579				ret.value = value += "";
8580
8581				// Break association with cloned elements by also using setAttribute (#9646)
8582				if ( name === "value" || value === elem.getAttribute( name ) ) {
8583					return value;
8584				}
8585			}
8586		};
8587
8588		// Some attributes are constructed with empty-string values when not defined
8589		attrHandle.id = attrHandle.name = attrHandle.coords =
8590			function( elem, name, isXML ) {
8591				var ret;
8592				if ( !isXML ) {
8593					return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
8594						ret.value :
8595						null;
8596				}
8597			};
8598
8599		// Fixing value retrieval on a button requires this module
8600		jQuery.valHooks.button = {
8601			get: function( elem, name ) {
8602				var ret = elem.getAttributeNode( name );
8603				if ( ret && ret.specified ) {
8604					return ret.value;
8605				}
8606			},
8607			set: nodeHook.set
8608		};
8609
8610		// Set contenteditable to false on removals(#10429)
8611		// Setting to empty string throws an error as an invalid value
8612		jQuery.attrHooks.contenteditable = {
8613			set: function( elem, value, name ) {
8614				nodeHook.set( elem, value === "" ? false : value, name );
8615			}
8616		};
8617
8618		// Set width and height to auto instead of 0 on empty string( Bug #8150 )
8619		// This is for removals
8620		jQuery.each( [ "width", "height" ], function( i, name ) {
8621			jQuery.attrHooks[ name ] = {
8622				set: function( elem, value ) {
8623					if ( value === "" ) {
8624						elem.setAttribute( name, "auto" );
8625						return value;
8626					}
8627				}
8628			};
8629		} );
8630	}
8631
8632	if ( !support.style ) {
8633		jQuery.attrHooks.style = {
8634			get: function( elem ) {
8635
8636				// Return undefined in the case of empty string
8637				// Note: IE uppercases css property names, but if we were to .toLowerCase()
8638				// .cssText, that would destroy case sensitivity in URL's, like in "background"
8639				return elem.style.cssText || undefined;
8640			},
8641			set: function( elem, value ) {
8642				return ( elem.style.cssText = value + "" );
8643			}
8644		};
8645	}
8646
8647
8648
8649
8650	var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8651		rclickable = /^(?:a|area)$/i;
8652
8653	jQuery.fn.extend( {
8654		prop: function( name, value ) {
8655			return access( this, jQuery.prop, name, value, arguments.length > 1 );
8656		},
8657
8658		removeProp: function( name ) {
8659			name = jQuery.propFix[ name ] || name;
8660			return this.each( function() {
8661
8662				// try/catch handles cases where IE balks (such as removing a property on window)
8663				try {
8664					this[ name ] = undefined;
8665					delete this[ name ];
8666				} catch ( e ) {}
8667			} );
8668		}
8669	} );
8670
8671	jQuery.extend( {
8672		prop: function( elem, name, value ) {
8673			var ret, hooks,
8674				nType = elem.nodeType;
8675
8676			// Don't get/set properties on text, comment and attribute nodes
8677			if ( nType === 3 || nType === 8 || nType === 2 ) {
8678				return;
8679			}
8680
8681			if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8682
8683				// Fix name and attach hooks
8684				name = jQuery.propFix[ name ] || name;
8685				hooks = jQuery.propHooks[ name ];
8686			}
8687
8688			if ( value !== undefined ) {
8689				if ( hooks && "set" in hooks &&
8690					( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8691					return ret;
8692				}
8693
8694				return ( elem[ name ] = value );
8695			}
8696
8697			if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8698				return ret;
8699			}
8700
8701			return elem[ name ];
8702		},
8703
8704		propHooks: {
8705			tabIndex: {
8706				get: function( elem ) {
8707
8708					// elem.tabIndex doesn't always return the
8709					// correct value when it hasn't been explicitly set
8710					// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8711					// Use proper attribute retrieval(#12072)
8712					var tabindex = jQuery.find.attr( elem, "tabindex" );
8713
8714					return tabindex ?
8715						parseInt( tabindex, 10 ) :
8716						rfocusable.test( elem.nodeName ) ||
8717						rclickable.test( elem.nodeName ) && elem.href ?
8718							0 :
8719							-1;
8720				}
8721			}
8722		},
8723
8724		propFix: {
8725			"for": "htmlFor",
8726			"class": "className"
8727		}
8728	} );
8729
8730// Some attributes require a special call on IE
8731// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8732	if ( !support.hrefNormalized ) {
8733
8734		// href/src property should get the full normalized URL (#10299/#12915)
8735		jQuery.each( [ "href", "src" ], function( i, name ) {
8736			jQuery.propHooks[ name ] = {
8737				get: function( elem ) {
8738					return elem.getAttribute( name, 4 );
8739				}
8740			};
8741		} );
8742	}
8743
8744// Support: Safari, IE9+
8745// Accessing the selectedIndex property
8746// forces the browser to respect setting selected
8747// on the option
8748// The getter ensures a default option is selected
8749// when in an optgroup
8750	if ( !support.optSelected ) {
8751		jQuery.propHooks.selected = {
8752			get: function( elem ) {
8753				var parent = elem.parentNode;
8754
8755				if ( parent ) {
8756					parent.selectedIndex;
8757
8758					// Make sure that it also works with optgroups, see #5701
8759					if ( parent.parentNode ) {
8760						parent.parentNode.selectedIndex;
8761					}
8762				}
8763				return null;
8764			},
8765			set: function( elem ) {
8766				var parent = elem.parentNode;
8767				if ( parent ) {
8768					parent.selectedIndex;
8769
8770					if ( parent.parentNode ) {
8771						parent.parentNode.selectedIndex;
8772					}
8773				}
8774			}
8775		};
8776	}
8777
8778	jQuery.each( [
8779		"tabIndex",
8780		"readOnly",
8781		"maxLength",
8782		"cellSpacing",
8783		"cellPadding",
8784		"rowSpan",
8785		"colSpan",
8786		"useMap",
8787		"frameBorder",
8788		"contentEditable"
8789	], function() {
8790		jQuery.propFix[ this.toLowerCase() ] = this;
8791	} );
8792
8793// IE6/7 call enctype encoding
8794	if ( !support.enctype ) {
8795		jQuery.propFix.enctype = "encoding";
8796	}
8797
8798
8799
8800
8801	var rclass = /[\t\r\n\f]/g;
8802
8803	function getClass( elem ) {
8804		return jQuery.attr( elem, "class" ) || "";
8805	}
8806
8807	jQuery.fn.extend( {
8808		addClass: function( value ) {
8809			var classes, elem, cur, curValue, clazz, j, finalValue,
8810				i = 0;
8811
8812			if ( jQuery.isFunction( value ) ) {
8813				return this.each( function( j ) {
8814					jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8815				} );
8816			}
8817
8818			if ( typeof value === "string" && value ) {
8819				classes = value.match( rnotwhite ) || [];
8820
8821				while ( ( elem = this[ i++ ] ) ) {
8822					curValue = getClass( elem );
8823					cur = elem.nodeType === 1 &&
8824						( " " + curValue + " " ).replace( rclass, " " );
8825
8826					if ( cur ) {
8827						j = 0;
8828						while ( ( clazz = classes[ j++ ] ) ) {
8829							if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8830								cur += clazz + " ";
8831							}
8832						}
8833
8834						// only assign if different to avoid unneeded rendering.
8835						finalValue = jQuery.trim( cur );
8836						if ( curValue !== finalValue ) {
8837							jQuery.attr( elem, "class", finalValue );
8838						}
8839					}
8840				}
8841			}
8842
8843			return this;
8844		},
8845
8846		removeClass: function( value ) {
8847			var classes, elem, cur, curValue, clazz, j, finalValue,
8848				i = 0;
8849
8850			if ( jQuery.isFunction( value ) ) {
8851				return this.each( function( j ) {
8852					jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8853				} );
8854			}
8855
8856			if ( !arguments.length ) {
8857				return this.attr( "class", "" );
8858			}
8859
8860			if ( typeof value === "string" && value ) {
8861				classes = value.match( rnotwhite ) || [];
8862
8863				while ( ( elem = this[ i++ ] ) ) {
8864					curValue = getClass( elem );
8865
8866					// This expression is here for better compressibility (see addClass)
8867					cur = elem.nodeType === 1 &&
8868						( " " + curValue + " " ).replace( rclass, " " );
8869
8870					if ( cur ) {
8871						j = 0;
8872						while ( ( clazz = classes[ j++ ] ) ) {
8873
8874							// Remove *all* instances
8875							while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8876								cur = cur.replace( " " + clazz + " ", " " );
8877							}
8878						}
8879
8880						// Only assign if different to avoid unneeded rendering.
8881						finalValue = jQuery.trim( cur );
8882						if ( curValue !== finalValue ) {
8883							jQuery.attr( elem, "class", finalValue );
8884						}
8885					}
8886				}
8887			}
8888
8889			return this;
8890		},
8891
8892		toggleClass: function( value, stateVal ) {
8893			var type = typeof value;
8894
8895			if ( typeof stateVal === "boolean" && type === "string" ) {
8896				return stateVal ? this.addClass( value ) : this.removeClass( value );
8897			}
8898
8899			if ( jQuery.isFunction( value ) ) {
8900				return this.each( function( i ) {
8901					jQuery( this ).toggleClass(
8902						value.call( this, i, getClass( this ), stateVal ),
8903						stateVal
8904					);
8905				} );
8906			}
8907
8908			return this.each( function() {
8909				var className, i, self, classNames;
8910
8911				if ( type === "string" ) {
8912
8913					// Toggle individual class names
8914					i = 0;
8915					self = jQuery( this );
8916					classNames = value.match( rnotwhite ) || [];
8917
8918					while ( ( className = classNames[ i++ ] ) ) {
8919
8920						// Check each className given, space separated list
8921						if ( self.hasClass( className ) ) {
8922							self.removeClass( className );
8923						} else {
8924							self.addClass( className );
8925						}
8926					}
8927
8928					// Toggle whole class name
8929				} else if ( value === undefined || type === "boolean" ) {
8930					className = getClass( this );
8931					if ( className ) {
8932
8933						// store className if set
8934						jQuery._data( this, "__className__", className );
8935					}
8936
8937					// If the element has a class name or if we're passed "false",
8938					// then remove the whole classname (if there was one, the above saved it).
8939					// Otherwise bring back whatever was previously saved (if anything),
8940					// falling back to the empty string if nothing was stored.
8941					jQuery.attr( this, "class",
8942						className || value === false ?
8943							"" :
8944							jQuery._data( this, "__className__" ) || ""
8945					);
8946				}
8947			} );
8948		},
8949
8950		hasClass: function( selector ) {
8951			var className, elem,
8952				i = 0;
8953
8954			className = " " + selector + " ";
8955			while ( ( elem = this[ i++ ] ) ) {
8956				if ( elem.nodeType === 1 &&
8957					( " " + getClass( elem ) + " " ).replace( rclass, " " )
8958						.indexOf( className ) > -1
8959				) {
8960					return true;
8961				}
8962			}
8963
8964			return false;
8965		}
8966	} );
8967
8968
8969
8970
8971// Return jQuery for attributes-only inclusion
8972
8973
8974	jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
8975			"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8976			"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
8977		function( i, name ) {
8978
8979			// Handle event binding
8980			jQuery.fn[ name ] = function( data, fn ) {
8981				return arguments.length > 0 ?
8982					this.on( name, null, data, fn ) :
8983					this.trigger( name );
8984			};
8985		} );
8986
8987	jQuery.fn.extend( {
8988		hover: function( fnOver, fnOut ) {
8989			return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8990		}
8991	} );
8992
8993
8994	var location = window.location;
8995
8996	var nonce = jQuery.now();
8997
8998	var rquery = ( /\?/ );
8999
9000
9001
9002	var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
9003
9004	jQuery.parseJSON = function( data ) {
9005
9006		// Attempt to parse using the native JSON parser first
9007		if ( window.JSON && window.JSON.parse ) {
9008
9009			// Support: Android 2.3
9010			// Workaround failure to string-cast null input
9011			return window.JSON.parse( data + "" );
9012		}
9013
9014		var requireNonComma,
9015			depth = null,
9016			str = jQuery.trim( data + "" );
9017
9018		// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
9019		// after removing valid tokens
9020		return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
9021
9022			// Force termination if we see a misplaced comma
9023			if ( requireNonComma && comma ) {
9024				depth = 0;
9025			}
9026
9027			// Perform no more replacements after returning to outermost depth
9028			if ( depth === 0 ) {
9029				return token;
9030			}
9031
9032			// Commas must not follow "[", "{", or ","
9033			requireNonComma = open || comma;
9034
9035			// Determine new depth
9036			// array/object open ("[" or "{"): depth += true - false (increment)
9037			// array/object close ("]" or "}"): depth += false - true (decrement)
9038			// other cases ("," or primitive): depth += true - true (numeric cast)
9039			depth += !close - !open;
9040
9041			// Remove this token
9042			return "";
9043		} ) ) ?
9044			( Function( "return " + str ) )() :
9045			jQuery.error( "Invalid JSON: " + data );
9046	};
9047
9048
9049// Cross-browser xml parsing
9050	jQuery.parseXML = function( data ) {
9051		var xml, tmp;
9052		if ( !data || typeof data !== "string" ) {
9053			return null;
9054		}
9055		try {
9056			if ( window.DOMParser ) { // Standard
9057				tmp = new window.DOMParser();
9058				xml = tmp.parseFromString( data, "text/xml" );
9059			} else { // IE
9060				xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
9061				xml.async = "false";
9062				xml.loadXML( data );
9063			}
9064		} catch ( e ) {
9065			xml = undefined;
9066		}
9067		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
9068			jQuery.error( "Invalid XML: " + data );
9069		}
9070		return xml;
9071	};
9072
9073
9074	var
9075		rhash = /#.*$/,
9076		rts = /([?&])_=[^&]*/,
9077
9078		// IE leaves an \r character at EOL
9079		rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
9080
vendor: 9,595 bytes, lines 9081-9439
9081		// #7653, #8125, #8152: local protocol detection
9082		rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9083		rnoContent = /^(?:GET|HEAD)$/,
9084		rprotocol = /^\/\//,
9085		rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
9086
9087		/* Prefilters
9088	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9089	 * 2) These are called:
9090	 *    - BEFORE asking for a transport
9091	 *    - AFTER param serialization (s.data is a string if s.processData is true)
9092	 * 3) key is the dataType
9093	 * 4) the catchall symbol "*" can be used
9094	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9095	 */
9096		prefilters = {},
9097
9098		/* Transports bindings
9099	 * 1) key is the dataType
9100	 * 2) the catchall symbol "*" can be used
9101	 * 3) selection will start with transport dataType and THEN go to "*" if needed
9102	 */
9103		transports = {},
9104
9105		// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9106		allTypes = "*/".concat( "*" ),
9107
9108		// Document location
9109		ajaxLocation = location.href,
9110
9111		// Segment location into parts
9112		ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
9113
9114// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9115	function addToPrefiltersOrTransports( structure ) {
9116
9117		// dataTypeExpression is optional and defaults to "*"
9118		return function( dataTypeExpression, func ) {
9119
9120			if ( typeof dataTypeExpression !== "string" ) {
9121				func = dataTypeExpression;
9122				dataTypeExpression = "*";
9123			}
9124
9125			var dataType,
9126				i = 0,
9127				dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
9128
9129			if ( jQuery.isFunction( func ) ) {
9130
9131				// For each dataType in the dataTypeExpression
9132				while ( ( dataType = dataTypes[ i++ ] ) ) {
9133
9134					// Prepend if requested
9135					if ( dataType.charAt( 0 ) === "+" ) {
9136						dataType = dataType.slice( 1 ) || "*";
9137						( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9138
9139						// Otherwise append
9140					} else {
9141						( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9142					}
9143				}
9144			}
9145		};
9146	}
9147
9148// Base inspection function for prefilters and transports
9149	function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9150
9151		var inspected = {},
9152			seekingTransport = ( structure === transports );
9153
9154		function inspect( dataType ) {
9155			var selected;
9156			inspected[ dataType ] = true;
9157			jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9158				var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9159				if ( typeof dataTypeOrTransport === "string" &&
9160					!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9161
9162					options.dataTypes.unshift( dataTypeOrTransport );
9163					inspect( dataTypeOrTransport );
9164					return false;
9165				} else if ( seekingTransport ) {
9166					return !( selected = dataTypeOrTransport );
9167				}
9168			} );
9169			return selected;
9170		}
9171
9172		return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9173	}
9174
9175// A special extend for ajax options
9176// that takes "flat" options (not to be deep extended)
9177// Fixes #9887
9178	function ajaxExtend( target, src ) {
9179		var deep, key,
9180			flatOptions = jQuery.ajaxSettings.flatOptions || {};
9181
9182		for ( key in src ) {
9183			if ( src[ key ] !== undefined ) {
9184				( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9185			}
9186		}
9187		if ( deep ) {
9188			jQuery.extend( true, target, deep );
9189		}
9190
9191		return target;
9192	}
9193
9194	/* Handles responses to an ajax request:
9195 * - finds the right dataType (mediates between content-type and expected dataType)
9196 * - returns the corresponding response
9197 */
9198	function ajaxHandleResponses( s, jqXHR, responses ) {
9199		var firstDataType, ct, finalDataType, type,
9200			contents = s.contents,
9201			dataTypes = s.dataTypes;
9202
9203		// Remove auto dataType and get content-type in the process
9204		while ( dataTypes[ 0 ] === "*" ) {
9205			dataTypes.shift();
9206			if ( ct === undefined ) {
9207				ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9208			}
9209		}
9210
9211		// Check if we're dealing with a known content-type
9212		if ( ct ) {
9213			for ( type in contents ) {
9214				if ( contents[ type ] && contents[ type ].test( ct ) ) {
9215					dataTypes.unshift( type );
9216					break;
9217				}
9218			}
9219		}
9220
9221		// Check to see if we have a response for the expected dataType
9222		if ( dataTypes[ 0 ] in responses ) {
9223			finalDataType = dataTypes[ 0 ];
9224		} else {
9225
9226			// Try convertible dataTypes
9227			for ( type in responses ) {
9228				if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9229					finalDataType = type;
9230					break;
9231				}
9232				if ( !firstDataType ) {
9233					firstDataType = type;
9234				}
9235			}
9236
9237			// Or just use first one
9238			finalDataType = finalDataType || firstDataType;
9239		}
9240
9241		// If we found a dataType
9242		// We add the dataType to the list if needed
9243		// and return the corresponding response
9244		if ( finalDataType ) {
9245			if ( finalDataType !== dataTypes[ 0 ] ) {
9246				dataTypes.unshift( finalDataType );
9247			}
9248			return responses[ finalDataType ];
9249		}
9250	}
9251
9252	/* Chain conversions given the request and the original response
9253 * Also sets the responseXXX fields on the jqXHR instance
9254 */
9255	function ajaxConvert( s, response, jqXHR, isSuccess ) {
9256		var conv2, current, conv, tmp, prev,
9257			converters = {},
9258
9259			// Work with a copy of dataTypes in case we need to modify it for conversion
9260			dataTypes = s.dataTypes.slice();
9261
9262		// Create converters map with lowercased keys
9263		if ( dataTypes[ 1 ] ) {
9264			for ( conv in s.converters ) {
9265				converters[ conv.toLowerCase() ] = s.converters[ conv ];
9266			}
9267		}
9268
9269		current = dataTypes.shift();
9270
9271		// Convert to each sequential dataType
9272		while ( current ) {
9273
9274			if ( s.responseFields[ current ] ) {
9275				jqXHR[ s.responseFields[ current ] ] = response;
9276			}
9277
9278			// Apply the dataFilter if provided
9279			if ( !prev && isSuccess && s.dataFilter ) {
9280				response = s.dataFilter( response, s.dataType );
9281			}
9282
9283			prev = current;
9284			current = dataTypes.shift();
9285
9286			if ( current ) {
9287
9288				// There's only work to do if current dataType is non-auto
9289				if ( current === "*" ) {
9290
9291					current = prev;
9292
9293					// Convert response if prev dataType is non-auto and differs from current
9294				} else if ( prev !== "*" && prev !== current ) {
9295
9296					// Seek a direct converter
9297					conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9298
9299					// If none found, seek a pair
9300					if ( !conv ) {
9301						for ( conv2 in converters ) {
9302
9303							// If conv2 outputs current
9304							tmp = conv2.split( " " );
9305							if ( tmp[ 1 ] === current ) {
9306
9307								// If prev can be converted to accepted input
9308								conv = converters[ prev + " " + tmp[ 0 ] ] ||
9309									converters[ "* " + tmp[ 0 ] ];
9310								if ( conv ) {
9311
9312									// Condense equivalence converters
9313									if ( conv === true ) {
9314										conv = converters[ conv2 ];
9315
9316										// Otherwise, insert the intermediate dataType
9317									} else if ( converters[ conv2 ] !== true ) {
9318										current = tmp[ 0 ];
9319										dataTypes.unshift( tmp[ 1 ] );
9320									}
9321									break;
9322								}
9323							}
9324						}
9325					}
9326
9327					// Apply converter (if not an equivalence)
9328					if ( conv !== true ) {
9329
9330						// Unless errors are allowed to bubble, catch and return them
9331						if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
9332							response = conv( response );
9333						} else {
9334							try {
9335								response = conv( response );
9336							} catch ( e ) {
9337								return {
9338									state: "parsererror",
9339									error: conv ? e : "No conversion from " + prev + " to " + current
9340								};
9341							}
9342						}
9343					}
9344				}
9345			}
9346		}
9347
9348		return { state: "success", data: response };
9349	}
9350
9351	jQuery.extend( {
9352
9353		// Counter for holding the number of active queries
9354		active: 0,
9355
9356		// Last-Modified header cache for next request
9357		lastModified: {},
9358		etag: {},
9359
9360		ajaxSettings: {
9361			url: ajaxLocation,
9362			type: "GET",
9363			isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
9364			global: true,
9365			processData: true,
9366			async: true,
9367			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9368			/*
9369		timeout: 0,
9370		data: null,
9371		dataType: null,
9372		username: null,
9373		password: null,
9374		cache: null,
9375		throws: false,
9376		traditional: false,
9377		headers: {},
9378		*/
9379
9380			accepts: {
9381				"*": allTypes,
9382				text: "text/plain",
9383				html: "text/html",
9384				xml: "application/xml, text/xml",
9385				json: "application/json, text/javascript"
9386			},
9387
9388			contents: {
9389				xml: /\bxml\b/,
9390				html: /\bhtml/,
9391				json: /\bjson\b/
9392			},
9393
9394			responseFields: {
9395				xml: "responseXML",
9396				text: "responseText",
9397				json: "responseJSON"
9398			},
9399
9400			// Data converters
9401			// Keys separate source (or catchall "*") and destination types with a single space
9402			converters: {
9403
9404				// Convert anything to text
9405				"* text": String,
9406
9407				// Text to html (true = no transformation)
9408				"text html": true,
9409
9410				// Evaluate text as a json expression
9411				"text json": jQuery.parseJSON,
9412
9413				// Parse text as xml
9414				"text xml": jQuery.parseXML
9415			},
9416
9417			// For options that shouldn't be deep extended:
9418			// you can add your own custom options here if
9419			// and when you create one that shouldn't be
9420			// deep extended (see ajaxExtend)
9421			flatOptions: {
9422				url: true,
9423				context: true
9424			}
9425		},
9426
9427		// Creates a full fledged settings object into target
9428		// with both ajaxSettings and settings fields.
9429		// If target is omitted, writes into ajaxSettings.
9430		ajaxSetup: function( target, settings ) {
9431			return settings ?
9432
9433				// Building a settings object
9434				ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9435
9436				// Extending ajaxSettings
9437				ajaxExtend( jQuery.ajaxSettings, target );
9438		},
9439
vendor: 5,675 bytes, lines 9440-9646
9440		ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9441		ajaxTransport: addToPrefiltersOrTransports( transports ),
9442
9443		// Main method
9444		ajax: function( url, options ) {
9445
9446			// If url is an object, simulate pre-1.5 signature
9447			if ( typeof url === "object" ) {
9448				options = url;
9449				url = undefined;
9450			}
9451
9452			// Force options to be an object
9453			options = options || {};
9454
9455			var
9456
9457				// Cross-domain detection vars
9458				parts,
9459
9460				// Loop variable
9461				i,
9462
9463				// URL without anti-cache param
9464				cacheURL,
9465
9466				// Response headers as string
9467				responseHeadersString,
9468
9469				// timeout handle
9470				timeoutTimer,
9471
9472				// To know if global events are to be dispatched
9473				fireGlobals,
9474
9475				transport,
9476
9477				// Response headers
9478				responseHeaders,
9479
9480				// Create the final options object
9481				s = jQuery.ajaxSetup( {}, options ),
9482
9483				// Callbacks context
9484				callbackContext = s.context || s,
9485
9486				// Context for global events is callbackContext if it is a DOM node or jQuery collection
9487				globalEventContext = s.context &&
9488				( callbackContext.nodeType || callbackContext.jquery ) ?
9489					jQuery( callbackContext ) :
9490					jQuery.event,
9491
9492				// Deferreds
9493				deferred = jQuery.Deferred(),
9494				completeDeferred = jQuery.Callbacks( "once memory" ),
9495
9496				// Status-dependent callbacks
9497				statusCode = s.statusCode || {},
9498
9499				// Headers (they are sent all at once)
9500				requestHeaders = {},
9501				requestHeadersNames = {},
9502
9503				// The jqXHR state
9504				state = 0,
9505
9506				// Default abort message
9507				strAbort = "canceled",
9508
9509				// Fake xhr
9510				jqXHR = {
9511					readyState: 0,
9512
9513					// Builds headers hashtable if needed
9514					getResponseHeader: function( key ) {
9515						var match;
9516						if ( state === 2 ) {
9517							if ( !responseHeaders ) {
9518								responseHeaders = {};
9519								while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9520									responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
9521								}
9522							}
9523							match = responseHeaders[ key.toLowerCase() ];
9524						}
9525						return match == null ? null : match;
9526					},
9527
9528					// Raw string
9529					getAllResponseHeaders: function() {
9530						return state === 2 ? responseHeadersString : null;
9531					},
9532
9533					// Caches the header
9534					setRequestHeader: function( name, value ) {
9535						var lname = name.toLowerCase();
9536						if ( !state ) {
9537							name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9538							requestHeaders[ name ] = value;
9539						}
9540						return this;
9541					},
9542
9543					// Overrides response content-type header
9544					overrideMimeType: function( type ) {
9545						if ( !state ) {
9546							s.mimeType = type;
9547						}
9548						return this;
9549					},
9550
9551					// Status-dependent callbacks
9552					statusCode: function( map ) {
9553						var code;
9554						if ( map ) {
9555							if ( state < 2 ) {
9556								for ( code in map ) {
9557
9558									// Lazy-add the new callback in a way that preserves old ones
9559									statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9560								}
9561							} else {
9562
9563								// Execute the appropriate callbacks
9564								jqXHR.always( map[ jqXHR.status ] );
9565							}
9566						}
9567						return this;
9568					},
9569
9570					// Cancel the request
9571					abort: function( statusText ) {
9572						var finalText = statusText || strAbort;
9573						if ( transport ) {
9574							transport.abort( finalText );
9575						}
9576						done( 0, finalText );
9577						return this;
9578					}
9579				};
9580
9581			// Attach deferreds
9582			deferred.promise( jqXHR ).complete = completeDeferred.add;
9583			jqXHR.success = jqXHR.done;
9584			jqXHR.error = jqXHR.fail;
9585
9586			// Remove hash character (#7531: and string promotion)
9587			// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9588			// Handle falsy url in the settings object (#10093: consistency with old signature)
9589			// We also use the url parameter if available
9590			s.url = ( ( url || s.url || ajaxLocation ) + "" )
9591				.replace( rhash, "" )
9592				.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9593
9594			// Alias method option to type as per ticket #12004
9595			s.type = options.method || options.type || s.method || s.type;
9596
9597			// Extract dataTypes list
9598			s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9599
9600			// A cross-domain request is in order when we have a protocol:host:port mismatch
9601			if ( s.crossDomain == null ) {
9602				parts = rurl.exec( s.url.toLowerCase() );
9603				s.crossDomain = !!( parts &&
9604					( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9605						( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9606						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9607				);
9608			}
9609
9610			// Convert data if not already a string
9611			if ( s.data && s.processData && typeof s.data !== "string" ) {
9612				s.data = jQuery.param( s.data, s.traditional );
9613			}
9614
9615			// Apply prefilters
9616			inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9617
9618			// If request was aborted inside a prefilter, stop there
9619			if ( state === 2 ) {
9620				return jqXHR;
9621			}
9622
9623			// We can fire global events as of now if asked to
9624			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9625			fireGlobals = jQuery.event && s.global;
9626
9627			// Watch for a new set of requests
9628			if ( fireGlobals && jQuery.active++ === 0 ) {
9629				jQuery.event.trigger( "ajaxStart" );
9630			}
9631
9632			// Uppercase the type
9633			s.type = s.type.toUpperCase();
9634
9635			// Determine if request has content
9636			s.hasContent = !rnoContent.test( s.type );
9637
9638			// Save the URL in case we're toying with the If-Modified-Since
9639			// and/or If-None-Match header later on
9640			cacheURL = s.url;
9641
9642			// More options handling for requests with no content
9643			if ( !s.hasContent ) {
9644
9645				// If data is available, append data to url
9646				if ( s.data ) {
vendor: 8,516 bytes, lines 9647-9986
9647					cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9648
9649					// #9682: remove data so that it's not used in an eventual retry
9650					delete s.data;
9651				}
9652
9653				// Add anti-cache in url if needed
9654				if ( s.cache === false ) {
9655					s.url = rts.test( cacheURL ) ?
9656
9657						// If there is already a '_' parameter, set its value
9658						cacheURL.replace( rts, "$1_=" + nonce++ ) :
9659
9660						// Otherwise add one to the end
9661						cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9662				}
9663			}
9664
9665			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9666			if ( s.ifModified ) {
9667				if ( jQuery.lastModified[ cacheURL ] ) {
9668					jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9669				}
9670				if ( jQuery.etag[ cacheURL ] ) {
9671					jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9672				}
9673			}
9674
9675			// Set the correct header, if data is being sent
9676			if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9677				jqXHR.setRequestHeader( "Content-Type", s.contentType );
9678			}
9679
9680			// Set the Accepts header for the server, depending on the dataType
9681			jqXHR.setRequestHeader(
9682				"Accept",
9683				s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9684					s.accepts[ s.dataTypes[ 0 ] ] +
9685					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9686					s.accepts[ "*" ]
9687			);
9688
9689			// Check for headers option
9690			for ( i in s.headers ) {
9691				jqXHR.setRequestHeader( i, s.headers[ i ] );
9692			}
9693
9694			// Allow custom headers/mimetypes and early abort
9695			if ( s.beforeSend &&
9696				( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9697
9698				// Abort if not done already and return
9699				return jqXHR.abort();
9700			}
9701
9702			// aborting is no longer a cancellation
9703			strAbort = "abort";
9704
9705			// Install callbacks on deferreds
9706			for ( i in { success: 1, error: 1, complete: 1 } ) {
9707				jqXHR[ i ]( s[ i ] );
9708			}
9709
9710			// Get transport
9711			transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9712
9713			// If no transport, we auto-abort
9714			if ( !transport ) {
9715				done( -1, "No Transport" );
9716			} else {
9717				jqXHR.readyState = 1;
9718
9719				// Send global event
9720				if ( fireGlobals ) {
9721					globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9722				}
9723
9724				// If request was aborted inside ajaxSend, stop there
9725				if ( state === 2 ) {
9726					return jqXHR;
9727				}
9728
9729				// Timeout
9730				if ( s.async && s.timeout > 0 ) {
9731					timeoutTimer = window.setTimeout( function() {
9732						jqXHR.abort( "timeout" );
9733					}, s.timeout );
9734				}
9735
9736				try {
9737					state = 1;
9738					transport.send( requestHeaders, done );
9739				} catch ( e ) {
9740
9741					// Propagate exception as error if not done
9742					if ( state < 2 ) {
9743						done( -1, e );
9744
9745						// Simply rethrow otherwise
9746					} else {
9747						throw e;
9748					}
9749				}
9750			}
9751
9752			// Callback for when everything is done
9753			function done( status, nativeStatusText, responses, headers ) {
9754				var isSuccess, success, error, response, modified,
9755					statusText = nativeStatusText;
9756
9757				// Called once
9758				if ( state === 2 ) {
9759					return;
9760				}
9761
9762				// State is "done" now
9763				state = 2;
9764
9765				// Clear timeout if it exists
9766				if ( timeoutTimer ) {
9767					window.clearTimeout( timeoutTimer );
9768				}
9769
9770				// Dereference transport for early garbage collection
9771				// (no matter how long the jqXHR object will be used)
9772				transport = undefined;
9773
9774				// Cache response headers
9775				responseHeadersString = headers || "";
9776
9777				// Set readyState
9778				jqXHR.readyState = status > 0 ? 4 : 0;
9779
9780				// Determine if successful
9781				isSuccess = status >= 200 && status < 300 || status === 304;
9782
9783				// Get response data
9784				if ( responses ) {
9785					response = ajaxHandleResponses( s, jqXHR, responses );
9786				}
9787
9788				// Convert no matter what (that way responseXXX fields are always set)
9789				response = ajaxConvert( s, response, jqXHR, isSuccess );
9790
9791				// If successful, handle type chaining
9792				if ( isSuccess ) {
9793
9794					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9795					if ( s.ifModified ) {
9796						modified = jqXHR.getResponseHeader( "Last-Modified" );
9797						if ( modified ) {
9798							jQuery.lastModified[ cacheURL ] = modified;
9799						}
9800						modified = jqXHR.getResponseHeader( "etag" );
9801						if ( modified ) {
9802							jQuery.etag[ cacheURL ] = modified;
9803						}
9804					}
9805
9806					// if no content
9807					if ( status === 204 || s.type === "HEAD" ) {
9808						statusText = "nocontent";
9809
9810						// if not modified
9811					} else if ( status === 304 ) {
9812						statusText = "notmodified";
9813
9814						// If we have data, let's convert it
9815					} else {
9816						statusText = response.state;
9817						success = response.data;
9818						error = response.error;
9819						isSuccess = !error;
9820					}
9821				} else {
9822
9823					// We extract error from statusText
9824					// then normalize statusText and status for non-aborts
9825					error = statusText;
9826					if ( status || !statusText ) {
9827						statusText = "error";
9828						if ( status < 0 ) {
9829							status = 0;
9830						}
9831					}
9832				}
9833
9834				// Set data for the fake xhr object
9835				jqXHR.status = status;
9836				jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9837
9838				// Success/Error
9839				if ( isSuccess ) {
9840					deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9841				} else {
9842					deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9843				}
9844
9845				// Status-dependent callbacks
9846				jqXHR.statusCode( statusCode );
9847				statusCode = undefined;
9848
9849				if ( fireGlobals ) {
9850					globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9851						[ jqXHR, s, isSuccess ? success : error ] );
9852				}
9853
9854				// Complete
9855				completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9856
9857				if ( fireGlobals ) {
9858					globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9859
9860					// Handle the global AJAX counter
9861					if ( !( --jQuery.active ) ) {
9862						jQuery.event.trigger( "ajaxStop" );
9863					}
9864				}
9865			}
9866
9867			return jqXHR;
9868		},
9869
9870		getJSON: function( url, data, callback ) {
9871			return jQuery.get( url, data, callback, "json" );
9872		},
9873
9874		getScript: function( url, callback ) {
9875			return jQuery.get( url, undefined, callback, "script" );
9876		}
9877	} );
9878
9879	jQuery.each( [ "get", "post" ], function( i, method ) {
9880		jQuery[ method ] = function( url, data, callback, type ) {
9881
9882			// shift arguments if data argument was omitted
9883			if ( jQuery.isFunction( data ) ) {
9884				type = type || callback;
9885				callback = data;
9886				data = undefined;
9887			}
9888
9889			// The url can be an options object (which then must have .url)
9890			return jQuery.ajax( jQuery.extend( {
9891				url: url,
9892				type: method,
9893				dataType: type,
9894				data: data,
9895				success: callback
9896			}, jQuery.isPlainObject( url ) && url ) );
9897		};
9898	} );
9899
9900
9901	jQuery._evalUrl = function( url ) {
9902		return jQuery.ajax( {
9903			url: url,
9904
9905			// Make this explicit, since user can override this through ajaxSetup (#11264)
9906			type: "GET",
9907			dataType: "script",
9908			cache: true,
9909			async: false,
9910			global: false,
9911			"throws": true
9912		} );
9913	};
9914
9915
9916	jQuery.fn.extend( {
9917		wrapAll: function( html ) {
9918			if ( jQuery.isFunction( html ) ) {
9919				return this.each( function( i ) {
9920					jQuery( this ).wrapAll( html.call( this, i ) );
9921				} );
9922			}
9923
9924			if ( this[ 0 ] ) {
9925
9926				// The elements to wrap the target around
9927				var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9928
9929				if ( this[ 0 ].parentNode ) {
9930					wrap.insertBefore( this[ 0 ] );
9931				}
9932
9933				wrap.map( function() {
9934					var elem = this;
9935
9936					while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9937						elem = elem.firstChild;
9938					}
9939
9940					return elem;
9941				} ).append( this );
9942			}
9943
9944			return this;
9945		},
9946
9947		wrapInner: function( html ) {
9948			if ( jQuery.isFunction( html ) ) {
9949				return this.each( function( i ) {
9950					jQuery( this ).wrapInner( html.call( this, i ) );
9951				} );
9952			}
9953
9954			return this.each( function() {
9955				var self = jQuery( this ),
9956					contents = self.contents();
9957
9958				if ( contents.length ) {
9959					contents.wrapAll( html );
9960
9961				} else {
9962					self.append( html );
9963				}
9964			} );
9965		},
9966
9967		wrap: function( html ) {
9968			var isFunction = jQuery.isFunction( html );
9969
9970			return this.each( function( i ) {
9971				jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9972			} );
9973		},
9974
9975		unwrap: function() {
9976			return this.parent().each( function() {
9977				if ( !jQuery.nodeName( this, "body" ) ) {
9978					jQuery( this ).replaceWith( this.childNodes );
9979				}
9980			} ).end();
9981		}
9982	} );
9983
9984
9985	function getDisplay( elem ) {
9986		return elem.style && elem.style.display || jQuery.css( elem, "dis
9986play" );
9987	}
9988
9989	function filterHidden( elem ) {
9990
9991		// Disconnected elements are considered hidden
9992		if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
9993			return true;
9994		}
9995		while ( elem && elem.nodeType === 1 ) {
9996			if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
9997				return true;
9998			}
9999			elem = elem.parentNode;
10000		}
10001		return false;
10002	}
10003
10004	jQuery.expr.filters.hidden = function( elem ) {
10005
10006		// Support: Opera <= 12.12
10007		// Opera reports offsetWidths and offsetHeights less than zero on some elements
10008		return support.reliableHiddenOffsets() ?
10009			( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
10010				!elem.getClientRects().length ) :
10011			filterHidden( elem );
10012	};
10013
10014	jQuery.expr.filters.visible = function( elem ) {
10015		return !jQuery.expr.filters.hidden( elem );
10016	};
10017
10018
10019
10020
10021	var r20 = /%20/g,
10022		rbracket = /\[\]$/,
10023		rCRLF = /\r?\n/g,
10024		rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10025		rsubmittable = /^(?:input|select|textarea|keygen)/i;
10026
10027	function buildParams( prefix, obj, traditional, add ) {
10028		var name;
10029
10030		if ( jQuery.isArray( obj ) ) {
10031
10032			// Serialize array item.
10033			jQuery.each( obj, function( i, v ) {
10034				if ( traditional || rbracket.test( prefix ) ) {
10035
10036					// Treat each array item as a scalar.
10037					add( prefix, v );
10038
10039				} else {
10040
10041					// Item is non-scalar (array or object), encode its numeric index.
10042					buildParams(
10043						prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10044						v,
10045						traditional,
10046						add
10047					);
10048				}
10049			} );
10050
10051		} else if ( !traditional && jQuery.type( obj ) === "object" ) {
10052
10053			// Serialize object item.
10054			for ( name in obj ) {
10055				buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10056			}
10057
10058		} else {
10059
10060			// Serialize scalar item.
10061			add( prefix, obj );
10062		}
10063	}
10064
10065// Serialize an array of form elements or a set of
10066// key/values into a query string
10067	jQuery.param = function( a, traditional ) {
10068		var prefix,
10069			s = [],
10070			add = function( key, value ) {
10071
10072				// If value is a function, invoke it and return its value
10073				value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
10074				s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
10075			};
10076
10077		// Set traditional to true for jQuery <= 1.3.2 behavior.
10078		if ( traditional === undefined ) {
10079			traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
10080		}
10081
10082		// If an array was passed in, assume that it is an array of form elements.
10083		if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10084
10085			// Serialize the form elements
10086			jQuery.each( a, function() {
10087				add( this.name, this.value );
10088			} );
10089
10090		} else {
10091
10092			// If traditional, encode the "old" way (the way 1.3.2 or older
10093			// did it), otherwise encode params recursively.
10094			for ( prefix in a ) {
10095				buildParams( prefix, a[ prefix ], traditional, add );
10096			}
10097		}
10098
10099		// Return the resulting serialization
10100		return s.join( "&" ).replace( r20, "+" );
10101	};
10102
10103	jQuery.fn.extend( {
10104		serialize: function() {
10105			return jQuery.param( this.serializeArray() );
10106		},
10107		serializeArray: function() {
10108			return this.map( function() {
10109
10110				// Can add propHook for "elements" to filter or add form elements
10111				var elements = jQuery.prop( this, "elements" );
10112				return elements ? jQuery.makeArray( elements ) : this;
10113			} )
10114				.filter( function() {
10115					var type = this.type;
10116
10117					// Use .is(":disabled") so that fieldset[disabled] works
10118					return this.name && !jQuery( this ).is( ":disabled" ) &&
10119						rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10120						( this.checked || !rcheckableType.test( type ) );
10121				} )
10122				.map( function( i, elem ) {
10123					var val = jQuery( this ).val();
10124
10125					return val == null ?
10126						null :
10127						jQuery.isArray( val ) ?
10128							jQuery.map( val, function( val ) {
10129								return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10130							} ) :
10131							{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10132				} ).get();
10133		}
10134	} );
10135
10136
10137// Create the request object
10138// (This is still attached to ajaxSettings for backward compatibility)
10139	jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
10140
vendor: 23,392 bytes, lines 10141-10969
10141		// Support: IE6-IE8
10142		function() {
10143
10144			// XHR cannot access local files, always use ActiveX for that case
10145			if ( this.isLocal ) {
10146				return createActiveXHR();
10147			}
10148
10149			// Support: IE 9-11
10150			// IE seems to error on cross-domain PATCH requests when ActiveX XHR
10151			// is used. In IE 9+ always use the native XHR.
10152			// Note: this condition won't catch Edge as it doesn't define
10153			// document.documentMode but it also doesn't support ActiveX so it won't
10154			// reach this code.
10155			if ( document.documentMode > 8 ) {
10156				return createStandardXHR();
10157			}
10158
10159			// Support: IE<9
10160			// oldIE XHR does not support non-RFC2616 methods (#13240)
10161			// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
10162			// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
10163			// Although this check for six methods instead of eight
10164			// since IE also does not support "trace" and "connect"
10165			return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
10166				createStandardXHR() || createActiveXHR();
10167		} :
10168
10169		// For all other browsers, use the standard XMLHttpRequest object
10170		createStandardXHR;
10171
10172	var xhrId = 0,
10173		xhrCallbacks = {},
10174		xhrSupported = jQuery.ajaxSettings.xhr();
10175
10176// Support: IE<10
10177// Open requests must be manually aborted on unload (#5280)
10178// See https://support.microsoft.com/kb/2856746 for more info
10179	if ( window.attachEvent ) {
10180		window.attachEvent( "onunload", function() {
10181			for ( var key in xhrCallbacks ) {
10182				xhrCallbacks[ key ]( undefined, true );
10183			}
10184		} );
10185	}
10186
10187// Determine support properties
10188	support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10189	xhrSupported = support.ajax = !!xhrSupported;
10190
10191// Create transport if the browser can provide an xhr
10192	if ( xhrSupported ) {
10193
10194		jQuery.ajaxTransport( function( options ) {
10195
10196			// Cross domain only allowed if supported through XMLHttpRequest
10197			if ( !options.crossDomain || support.cors ) {
10198
10199				var callback;
10200
10201				return {
10202					send: function( headers, complete ) {
10203						var i,
10204							xhr = options.xhr(),
10205							id = ++xhrId;
10206
10207						// Open the socket
10208						xhr.open(
10209							options.type,
10210							options.url,
10211							options.async,
10212							options.username,
10213							options.password
10214						);
10215
10216						// Apply custom fields if provided
10217						if ( options.xhrFields ) {
10218							for ( i in options.xhrFields ) {
10219								xhr[ i ] = options.xhrFields[ i ];
10220							}
10221						}
10222
10223						// Override mime type if needed
10224						if ( options.mimeType && xhr.overrideMimeType ) {
10225							xhr.overrideMimeType( options.mimeType );
10226						}
10227
10228						// X-Requested-With header
10229						// For cross-domain requests, seeing as conditions for a preflight are
10230						// akin to a jigsaw puzzle, we simply never set it to be sure.
10231						// (it can always be set on a per-request basis or even using ajaxSetup)
10232						// For same-domain requests, won't change header if already provided.
10233						if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10234							headers[ "X-Requested-With" ] = "XMLHttpRequest";
10235						}
10236
10237						// Set headers
10238						for ( i in headers ) {
10239
10240							// Support: IE<9
10241							// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
10242							// request header to a null-value.
10243							//
10244							// To keep consistent with other XHR implementations, cast the value
10245							// to string and ignore `undefined`.
10246							if ( headers[ i ] !== undefined ) {
10247								xhr.setRequestHeader( i, headers[ i ] + "" );
10248							}
10249						}
10250
10251						// Do send the request
10252						// This may raise an exception which is actually
10253						// handled in jQuery.ajax (so no try/catch here)
10254						xhr.send( ( options.hasContent && options.data ) || null );
10255
10256						// Listener
10257						callback = function( _, isAbort ) {
10258							var status, statusText, responses;
10259
10260							// Was never called and is aborted or complete
10261							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
10262
10263								// Clean up
10264								delete xhrCallbacks[ id ];
10265								callback = undefined;
10266								xhr.onreadystatechange = jQuery.noop;
10267
10268								// Abort manually if needed
10269								if ( isAbort ) {
10270									if ( xhr.readyState !== 4 ) {
10271										xhr.abort();
10272									}
10273								} else {
10274									responses = {};
10275									status = xhr.status;
10276
10277									// Support: IE<10
10278									// Accessing binary-data responseText throws an exception
10279									// (#11426)
10280									if ( typeof xhr.responseText === "string" ) {
10281										responses.text = xhr.responseText;
10282									}
10283
10284									// Firefox throws an exception when accessing
10285									// statusText for faulty cross-domain requests
10286									try {
10287										statusText = xhr.statusText;
10288									} catch ( e ) {
10289
10290										// We normalize with Webkit giving an empty statusText
10291										statusText = "";
10292									}
10293
10294									// Filter status for non standard behaviors
10295
10296									// If the request is local and we have data: assume a success
10297									// (success with no data won't get notified, that's the best we
10298									// can do given current implementations)
10299									if ( !status && options.isLocal && !options.crossDomain ) {
10300										status = responses.text ? 200 : 404;
10301
10302										// IE - #1450: sometimes returns 1223 when it should be 204
10303									} else if ( status === 1223 ) {
10304										status = 204;
10305									}
10306								}
10307							}
10308
10309							// Call complete if needed
10310							if ( responses ) {
10311								complete( status, statusText, responses, xhr.getAllResponseHeaders() );
10312							}
10313						};
10314
10315						// Do send the request
10316						// `xhr.send` may raise an exception, but it will be
10317						// handled in jQuery.ajax (so no try/catch here)
10318						if ( !options.async ) {
10319
10320							// If we're in sync mode we fire the callback
10321							callback();
10322						} else if ( xhr.readyState === 4 ) {
10323
10324							// (IE6 & IE7) if it's in cache and has been
10325							// retrieved directly we need to fire the callback
10326							window.setTimeout( callback );
10327						} else {
10328
10329							// Register the callback, but delay it in case `xhr.send` throws
10330							// Add to the list of active xhr callbacks
10331							xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
10332						}
10333					},
10334
10335					abort: function() {
10336						if ( callback ) {
10337							callback( undefined, true );
10338						}
10339					}
10340				};
10341			}
10342		} );
10343	}
10344
10345// Functions to create xhrs
10346	function createStandardXHR() {
10347		try {
10348			return new window.XMLHttpRequest();
10349		} catch ( e ) {}
10350	}
10351
10352	function createActiveXHR() {
10353		try {
10354			return new window.ActiveXObject( "Microsoft.XMLHTTP" );
10355		} catch ( e ) {}
10356	}
10357
10358
10359
10360
10361// Install script dataType
10362	jQuery.ajaxSetup( {
10363		accepts: {
10364			script: "text/javascript, application/javascript, " +
10365				"application/ecmascript, application/x-ecmascript"
10366		},
10367		contents: {
10368			script: /\b(?:java|ecma)script\b/
10369		},
10370		converters: {
10371			"text script": function( text ) {
10372				jQuery.globalEval( text );
10373				return text;
10374			}
10375		}
10376	} );
10377
10378// Handle cache's special case and global
10379	jQuery.ajaxPrefilter( "script", function( s ) {
10380		if ( s.cache === undefined ) {
10381			s.cache = false;
10382		}
10383		if ( s.crossDomain ) {
10384			s.type = "GET";
10385			s.global = false;
10386		}
10387	} );
10388
10389// Bind script tag hack transport
10390	jQuery.ajaxTransport( "script", function( s ) {
10391
10392		// This transport only deals with cross domain requests
10393		if ( s.crossDomain ) {
10394
10395			var script,
10396				head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
10397
10398			return {
10399
10400				send: function( _, callback ) {
10401
10402					script = document.createElement( "script" );
10403
10404					script.async = true;
10405
10406					if ( s.scriptCharset ) {
10407						script.charset = s.scriptCharset;
10408					}
10409
10410					script.src = s.url;
10411
10412					// Attach handlers for all browsers
10413					script.onload = script.onreadystatechange = function( _, isAbort ) {
10414
10415						if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
10416
10417							// Handle memory leak in IE
10418							script.onload = script.onreadystatechange = null;
10419
10420							// Remove the script
10421							if ( script.parentNode ) {
10422								script.parentNode.removeChild( script );
10423							}
10424
10425							// Dereference the script
10426							script = null;
10427
10428							// Callback if not abort
10429							if ( !isAbort ) {
10430								callback( 200, "success" );
10431							}
10432						}
10433					};
10434
10435					// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
10436					// Use native DOM manipulation to avoid our domManip AJAX trickery
10437					head.insertBefore( script, head.firstChild );
10438				},
10439
10440				abort: function() {
10441					if ( script ) {
10442						script.onload( undefined, true );
10443					}
10444				}
10445			};
10446		}
10447	} );
10448
10449
10450
10451
10452	var oldCallbacks = [],
10453		rjsonp = /(=)\?(?=&|$)|\?\?/;
10454
10455// Default jsonp settings
10456	jQuery.ajaxSetup( {
10457		jsonp: "callback",
10458		jsonpCallback: function() {
10459			var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
10460			this[ callback ] = true;
10461			return callback;
10462		}
10463	} );
10464
10465// Detect, normalize options and install callbacks for jsonp requests
10466	jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10467
10468		var callbackName, overwritten, responseContainer,
10469			jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10470					"url" :
10471					typeof s.data === "string" &&
10472					( s.contentType || "" )
10473						.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10474					rjsonp.test( s.data ) && "data"
10475			);
10476
10477		// Handle iff the expected data type is "jsonp" or we have a parameter to set
10478		if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10479
10480			// Get callback name, remembering preexisting value associated with it
10481			callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
10482				s.jsonpCallback() :
10483				s.jsonpCallback;
10484
10485			// Insert callback into url or form data
10486			if ( jsonProp ) {
10487				s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10488			} else if ( s.jsonp !== false ) {
10489				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10490			}
10491
10492			// Use data converter to retrieve json after script execution
10493			s.converters[ "script json" ] = function() {
10494				if ( !responseContainer ) {
10495					jQuery.error( callbackName + " was not called" );
10496				}
10497				return responseContainer[ 0 ];
10498			};
10499
10500			// force json dataType
10501			s.dataTypes[ 0 ] = "json";
10502
10503			// Install callback
10504			overwritten = window[ callbackName ];
10505			window[ callbackName ] = function() {
10506				responseContainer = arguments;
10507			};
10508
10509			// Clean-up function (fires after converters)
10510			jqXHR.always( function() {
10511
10512				// If previous value didn't exist - remove it
10513				if ( overwritten === undefined ) {
10514					jQuery( window ).removeProp( callbackName );
10515
10516					// Otherwise restore preexisting value
10517				} else {
10518					window[ callbackName ] = overwritten;
10519				}
10520
10521				// Save back as free
10522				if ( s[ callbackName ] ) {
10523
10524					// make sure that re-using the options doesn't screw things around
10525					s.jsonpCallback = originalSettings.jsonpCallback;
10526
10527					// save the callback name for future use
10528					oldCallbacks.push( callbackName );
10529				}
10530
10531				// Call if it was a function and we have a response
10532				if ( responseContainer && jQuery.isFunction( overwritten ) ) {
10533					overwritten( responseContainer[ 0 ] );
10534				}
10535
10536				responseContainer = overwritten = undefined;
10537			} );
10538
10539			// Delegate to script
10540			return "script";
10541		}
10542	} );
10543
10544
10545
10546
10547// data: string of html
10548// context (optional): If specified, the fragment will be created in this context,
10549// defaults to document
10550// keepScripts (optional): If true, will include scripts passed in the html string
10551	jQuery.parseHTML = function( data, context, keepScripts ) {
10552		if ( !data || typeof data !== "string" ) {
10553			return null;
10554		}
10555		if ( typeof context === "boolean" ) {
10556			keepScripts = context;
10557			context = false;
10558		}
10559		context = context || document;
10560
10561		var parsed = rsingleTag.exec( data ),
10562			scripts = !keepScripts && [];
10563
10564		// Single tag
10565		if ( parsed ) {
10566			return [ context.createElement( parsed[ 1 ] ) ];
10567		}
10568
10569		parsed = buildFragment( [ data ], context, scripts );
10570
10571		if ( scripts && scripts.length ) {
10572			jQuery( scripts ).remove();
10573		}
10574
10575		return jQuery.merge( [], parsed.childNodes );
10576	};
10577
10578
10579// Keep a copy of the old load method
10580	var _load = jQuery.fn.load;
10581
10582	/**
10583	 * Load a url into a page
10584	 */
10585	jQuery.fn.load = function( url, params, callback ) {
10586		if ( typeof url !== "string" && _load ) {
10587			return _load.apply( this, arguments );
10588		}
10589
10590		var selector, type, response,
10591			self = this,
10592			off = url.indexOf( " " );
10593
10594		if ( off > -1 ) {
10595			selector = jQuery.trim( url.slice( off, url.length ) );
10596			url = url.slice( 0, off );
10597		}
10598
10599		// If it's a function
10600		if ( jQuery.isFunction( params ) ) {
10601
10602			// We assume that it's the callback
10603			callback = params;
10604			params = undefined;
10605
10606			// Otherwise, build a param string
10607		} else if ( params && typeof params === "object" ) {
10608			type = "POST";
10609		}
10610
10611		// If we have elements to modify, make the request
10612		if ( self.length > 0 ) {
10613			jQuery.ajax( {
10614				url: url,
10615
10616				// If "type" variable is undefined, then "GET" method will be used.
10617				// Make value of this field explicit since
10618				// user can override it through ajaxSetup method
10619				type: type || "GET",
10620				dataType: "html",
10621				data: params
10622			} ).done( function( responseText ) {
10623
10624				// Save response for use in complete callback
10625				response = arguments;
10626
10627				self.html( selector ?
10628
10629					// If a selector was specified, locate the right elements in a dummy div
10630					// Exclude scripts to avoid IE 'Permission Denied' errors
10631					jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10632
10633					// Otherwise use the full result
10634					responseText );
10635
10636				// If the request succeeds, this function gets "data", "status", "jqXHR"
10637				// but they are ignored because response was set above.
10638				// If it fails, this function gets "jqXHR", "status", "error"
10639			} ).always( callback && function( jqXHR, status ) {
10640				self.each( function() {
10641					callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10642				} );
10643			} );
10644		}
10645
10646		return this;
10647	};
10648
10649
10650
10651
10652// Attach a bunch of functions for handling common AJAX events
10653	jQuery.each( [
10654		"ajaxStart",
10655		"ajaxStop",
10656		"ajaxComplete",
10657		"ajaxError",
10658		"ajaxSuccess",
10659		"ajaxSend"
10660	], function( i, type ) {
10661		jQuery.fn[ type ] = function( fn ) {
10662			return this.on( type, fn );
10663		};
10664	} );
10665
10666
10667
10668
10669	jQuery.expr.filters.animated = function( elem ) {
10670		return jQuery.grep( jQuery.timers, function( fn ) {
10671			return elem === fn.elem;
10672		} ).length;
10673	};
10674
10675
10676
10677
10678
10679	/**
10680	 * Gets a window from an element
10681	 */
10682	function getWindow( elem ) {
10683		return jQuery.isWindow( elem ) ?
10684			elem :
10685			elem.nodeType === 9 ?
10686				elem.defaultView || elem.parentWindow :
10687				false;
10688	}
10689
10690	jQuery.offset = {
10691		setOffset: function( elem, options, i ) {
10692			var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10693				position = jQuery.css( elem, "position" ),
10694				curElem = jQuery( elem ),
10695				props = {};
10696
10697			// set position first, in-case top/left are set even on static elem
10698			if ( position === "static" ) {
10699				elem.style.position = "relative";
10700			}
10701
10702			curOffset = curElem.offset();
10703			curCSSTop = jQuery.css( elem, "top" );
10704			curCSSLeft = jQuery.css( elem, "left" );
10705			calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10706				jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
10707
10708			// need to be able to calculate position if either top or left
10709			// is auto and position is either absolute or fixed
10710			if ( calculatePosition ) {
10711				curPosition = curElem.position();
10712				curTop = curPosition.top;
10713				curLeft = curPosition.left;
10714			} else {
10715				curTop = parseFloat( curCSSTop ) || 0;
10716				curLeft = parseFloat( curCSSLeft ) || 0;
10717			}
10718
10719			if ( jQuery.isFunction( options ) ) {
10720
10721				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10722				options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10723			}
10724
10725			if ( options.top != null ) {
10726				props.top = ( options.top - curOffset.top ) + curTop;
10727			}
10728			if ( options.left != null ) {
10729				props.left = ( options.left - curOffset.left ) + curLeft;
10730			}
10731
10732			if ( "using" in options ) {
10733				options.using.call( elem, props );
10734			} else {
10735				curElem.css( props );
10736			}
10737		}
10738	};
10739
10740	jQuery.fn.extend( {
10741		offset: function( options ) {
10742			if ( arguments.length ) {
10743				return options === undefined ?
10744					this :
10745					this.each( function( i ) {
10746						jQuery.offset.setOffset( this, options, i );
10747					} );
10748			}
10749
10750			var docElem, win,
10751				box = { top: 0, left: 0 },
10752				elem = this[ 0 ],
10753				doc = elem && elem.ownerDocument;
10754
10755			if ( !doc ) {
10756				return;
10757			}
10758
10759			docElem = doc.documentElement;
10760
10761			// Make sure it's not a disconnected DOM node
10762			if ( !jQuery.contains( docElem, elem ) ) {
10763				return box;
10764			}
10765
10766			// If we don't have gBCR, just use 0,0 rather than error
10767			// BlackBerry 5, iOS 3 (original iPhone)
10768			if ( typeof elem.getBoundingClientRect !== "undefined" ) {
10769				box = elem.getBoundingClientRect();
10770			}
10771			win = getWindow( doc );
10772			return {
10773				top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
10774				left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10775			};
10776		},
10777
10778		position: function() {
10779			if ( !this[ 0 ] ) {
10780				return;
10781			}
10782
10783			var offsetParent, offset,
10784				parentOffset = { top: 0, left: 0 },
10785				elem = this[ 0 ];
10786
10787			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
10788			// because it is its only offset parent
10789			if ( jQuery.css( elem, "position" ) === "fixed" ) {
10790
10791				// we assume that getBoundingClientRect is available when computed position is fixed
10792				offset = elem.getBoundingClientRect();
10793			} else {
10794
10795				// Get *real* offsetParent
10796				offsetParent = this.offsetParent();
10797
10798				// Get correct offsets
10799				offset = this.offset();
10800				if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10801					parentOffset = offsetParent.offset();
10802				}
10803
10804				// Add offsetParent borders
10805				parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10806				parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10807			}
10808
10809			// Subtract parent offsets and element margins
10810			// note: when an element has margin: auto the offsetLeft and marginLeft
10811			// are the same in Safari causing offset.left to incorrectly be 0
10812			return {
10813				top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10814				left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10815			};
10816		},
10817
10818		offsetParent: function() {
10819			return this.map( function() {
10820				var offsetParent = this.offsetParent;
10821
10822				while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
10823					jQuery.css( offsetParent, "position" ) === "static" ) ) {
10824					offsetParent = offsetParent.offsetParent;
10825				}
10826				return offsetParent || documentElement;
10827			} );
10828		}
10829	} );
10830
10831// Create scrollLeft and scrollTop methods
10832	jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10833		var top = /Y/.test( prop );
10834
10835		jQuery.fn[ method ] = function( val ) {
10836			return access( this, function( elem, method, val ) {
10837				var win = getWindow( elem );
10838
10839				if ( val === undefined ) {
10840					return win ? ( prop in win ) ? win[ prop ] :
10841							win.document.documentElement[ method ] :
10842						elem[ method ];
10843				}
10844
10845				if ( win ) {
10846					win.scrollTo(
10847						!top ? val : jQuery( win ).scrollLeft(),
10848						top ? val : jQuery( win ).scrollTop()
10849					);
10850
10851				} else {
10852					elem[ method ] = val;
10853				}
10854			}, method, val, arguments.length, null );
10855		};
10856	} );
10857
10858// Support: Safari<7-8+, Chrome<37-44+
10859// Add the top/left cssHooks using jQuery.fn.position
10860// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10861// getComputedStyle returns percent when specified for top/left/bottom/right
10862// rather than make the css module depend on the offset module, we just check for it here
10863	jQuery.each( [ "top", "left" ], function( i, prop ) {
10864		jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10865			function( elem, computed ) {
10866				if ( computed ) {
10867					computed = curCSS( elem, prop );
10868
10869					// if curCSS returns percentage, fallback to offset
10870					return rnumnonpx.test( computed ) ?
10871						jQuery( elem ).position()[ prop ] + "px" :
10872						computed;
10873				}
10874			}
10875		);
10876	} );
10877
10878
10879// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10880	jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10881		jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10882			function( defaultExtra, funcName ) {
10883
10884				// margin is only for outerHeight, outerWidth
10885				jQuery.fn[ funcName ] = function( margin, value ) {
10886					var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10887						extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10888
10889					return access( this, function( elem, type, value ) {
10890						var doc;
10891
10892						if ( jQuery.isWindow( elem ) ) {
10893
10894							// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10895							// isn't a whole lot we can do. See pull request at this URL for discussion:
10896							// https://github.com/jquery/jquery/pull/764
10897							return elem.document.documentElement[ "client" + name ];
10898						}
10899
10900						// Get document width or height
10901						if ( elem.nodeType === 9 ) {
10902							doc = elem.documentElement;
10903
10904							// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10905							// whichever is greatest
10906							// unfortunately, this causes bug #3838 in IE6/8 only,
10907							// but there is currently no good, small way to fix it.
10908							return Math.max(
10909								elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10910								elem.body[ "offset" + name ], doc[ "offset" + name ],
10911								doc[ "client" + name ]
10912							);
10913						}
10914
10915						return value === undefined ?
10916
10917							// Get width or height on the element, requesting but not forcing parseFloat
10918							jQuery.css( elem, type, extra ) :
10919
10920							// Set width or height on the element
10921							jQuery.style( elem, type, value, extra );
10922					}, type, chainable ? margin : undefined, chainable, null );
10923				};
10924			} );
10925	} );
10926
10927
10928	jQuery.fn.extend( {
10929
10930		bind: function( types, data, fn ) {
10931			return this.on( types, null, data, fn );
10932		},
10933		unbind: function( types, fn ) {
10934			return this.off( types, null, fn );
10935		},
10936
10937		delegate: function( selector, types, data, fn ) {
10938			return this.on( types, selector, data, fn );
10939		},
10940		undelegate: function( selector, types, fn ) {
10941
10942			// ( namespace ) or ( selector, types [, fn] )
10943			return arguments.length === 1 ?
10944				this.off( selector, "**" ) :
10945				this.off( types, selector || "**", fn );
10946		}
10947	} );
10948
10949// The number of elements contained in the matched element set
10950	jQuery.fn.size = function() {
10951		return this.length;
10952	};
10953
10954	jQuery.fn.andSelf = jQuery.fn.addBack;
10955
10956
10957
10958
10959// Register as a named AMD module, since jQuery can be concatenated with other
10960// files that may use define, but not via a proper concatenation script that
10961// understands anonymous AMD modules. A named AMD is safest and most robust
10962// way to register. Lowercase jquery is used because AMD module names are
10963// derived from file names, and jQuery is normally delivered in a lowercase
10964// file name. Do this after creating the global so that if an AMD module wants
10965// to call noConflict to hide this version of jQuery, it will work.
10966
10967// Note that for maximum portability, libraries that are not jQuery should
10968// declare themselves as anonymous modules, and avoid setting a global if an
10969// AMD loader is present. jQuery is a special case. For more information, see
vendor: 4,812 bytes, lines 10970-11137
10970// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10971
10972	if ( typeof define === "function" && define.amd ) {
10973		define( "jquery", [], function() {
10974			return jQuery;
10975		} );
10976	}
10977
10978
10979
10980	var
10981
10982		// Map over jQuery in case of overwrite
10983		_jQuery = window.jQuery,
10984
10985		// Map over the $ in case of overwrite
10986		_$ = window.$;
10987
10988	jQuery.noConflict = function( deep ) {
10989		if ( window.$ === jQuery ) {
10990			window.$ = _$;
10991		}
10992
10993		if ( deep && window.jQuery === jQuery ) {
10994			window.jQuery = _jQuery;
10995		}
10996
10997		return jQuery;
10998	};
10999
11000// Expose jQuery and $ identifiers, even in
11001// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
11002// and CommonJS for browser emulators (#13566)
11003	if ( !noGlobal ) {
11004		window.jQuery = window.$ = jQuery;
11005	}
11006
11007	return jQuery;
11008}));
11009
11010/*!
11011  * Bootstrap v4.5.3 (https://getbootstrap.com/)
11012  * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
11013  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
11014  */
11015(function (global, factory) {
11016	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery')) :
11017		typeof define === 'function' && define.amd ? define(['exports', 'jquery'], factory) :
11018			(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bootstrap = {}, global.jQuery));
11019}(this, (function (exports, $) { 'use strict';
11020
11021	function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11022
11023	var $__default = /*#__PURE__*/_interopDefaultLegacy($);
11024
11025	function _defineProperties(target, props) {
11026		for (var i = 0; i < props.length; i++) {
11027			var descriptor = props[i];
11028			descriptor.enumerable = descriptor.enumerable || false;
11029			descriptor.configurable = true;
11030			if ("value" in descriptor) descriptor.writable = true;
11031			Object.defineProperty(target, descriptor.key, descriptor);
11032		}
11033	}
11034
11035	function _createClass(Constructor, protoProps, staticProps) {
11036		if (protoProps) _defineProperties(Constructor.prototype, protoProps);
11037		if (staticProps) _defineProperties(Constructor, staticProps);
11038		return Constructor;
11039	}
11040
11041	function _extends() {
11042		_extends = Object.assign || function (target) {
11043			for (var i = 1; i < arguments.length; i++) {
11044				var source = arguments[i];
11045
11046				for (var key in source) {
11047					if (Object.prototype.hasOwnProperty.call(source, key)) {
11048						target[key] = source[key];
11049					}
11050				}
11051			}
11052
11053			return target;
11054		};
11055
11056		return _extends.apply(this, arguments);
11057	}
11058
11059	function _inheritsLoose(subClass, superClass) {
11060		subClass.prototype = Object.create(superClass.prototype);
11061		subClass.prototype.constructor = subClass;
11062		subClass.__proto__ = superClass;
11063	}
11064
11065	/**
11066	 * --------------------------------------------------------------------------
11067	 * Bootstrap (v4.5.3): util.js
11068	 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
11069	 * --------------------------------------------------------------------------
11070	 */
11071	/**
11072	 * ------------------------------------------------------------------------
11073	 * Private TransitionEnd Helpers
11074	 * ------------------------------------------------------------------------
11075	 */
11076
11077	var TRANSITION_END = 'transitionend';
11078	var MAX_UID = 1000000;
11079	var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
11080
11081	function toType(obj) {
11082		if (obj === null || typeof obj === 'undefined') {
11083			return "" + obj;
11084		}
11085
11086		return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
11087	}
11088
11089	function getSpecialTransitionEndEvent() {
11090		return {
11091			bindType: TRANSITION_END,
11092			delegateType: TRANSITION_END,
11093			handle: function handle(event) {
11094				if ($__default['default'](event.target).is(this)) {
11095					return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
11096				}
11097
11098				return undefined;
11099			}
11100		};
11101	}
11102
11103	function transitionEndEmulator(duration) {
11104		var _this = this;
11105
11106		var called = false;
11107		$__default['default'](this).one(Util.TRANSITION_END, function () {
11108			called = true;
11109		});
11110		setTimeout(function () {
11111			if (!called) {
11112				Util.triggerTransitionEnd(_this);
11113			}
11114		}, duration);
11115		return this;
11116	}
11117
11118	function setTransitionEndSupport() {
11119		$__default['default'].fn.emulateTransitionEnd = transitionEndEmulator;
11120		$__default['default'].event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
11121	}
11122	/**
11123	 * --------------------------------------------------------------------------
11124	 * Public Util Api
11125	 * --------------------------------------------------------------------------
11126	 */
11127
11128
11129	var Util = {
11130		TRANSITION_END: 'bsTransitionEnd',
11131		getUID: function getUID(prefix) {
11132			do {
11133				prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
11134			} while (document.getElementById(prefix));
11135
11136			return prefix;
11137		},
vendor: 5,186 bytes, lines 11138-11297
11138		getSelectorFromElement: function getSelectorFromElement(element) {
11139			var selector = element.getAttribute('data-target');
11140
11141			if (!selector || selector === '#') {
11142				var hrefAttr = element.getAttribute('href');
11143				selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';
11144			}
11145
11146			try {
11147				return document.querySelector(selector) ? selector : null;
11148			} catch (_) {
11149				return null;
11150			}
11151		},
11152		getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {
11153			if (!element) {
11154				return 0;
11155			} // Get transition-duration of the element
11156
11157
11158			var transitionDuration = $__default['default'](element).css('transition-duration');
11159			var transitionDelay = $__default['default'](element).css('transition-delay');
11160			var floatTransitionDuration = parseFloat(transitionDuration);
11161			var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
11162
11163			if (!floatTransitionDuration && !floatTransitionDelay) {
11164				return 0;
11165			} // If multiple durations are defined, take the first
11166
11167
11168			transitionDuration = transitionDuration.split(',')[0];
11169			transitionDelay = transitionDelay.split(',')[0];
11170			return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
11171		},
11172		reflow: function reflow(element) {
11173			return element.offsetHeight;
11174		},
11175		triggerTransitionEnd: function triggerTransitionEnd(element) {
11176			$__default['default'](element).trigger(TRANSITION_END);
11177		},
11178		supportsTransitionEnd: function supportsTransitionEnd() {
11179			return Boolean(TRANSITION_END);
11180		},
11181		isElement: function isElement(obj) {
11182			return (obj[0] || obj).nodeType;
11183		},
11184		typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
11185			for (var property in configTypes) {
11186				if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
11187					var expectedTypes = configTypes[property];
11188					var value = config[property];
11189					var valueType = value && Util.isElement(value) ? 'element' : toType(value);
11190
11191					if (!new RegExp(expectedTypes).test(valueType)) {
11192						throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
11193					}
11194				}
11195			}
11196		},
11197		findShadowRoot: function findShadowRoot(element) {
11198			if (!document.documentElement.attachShadow) {
11199				return null;
11200			} // Can find the shadow root otherwise it'll return the document
11201
11202
11203			if (typeof element.getRootNode === 'function') {
11204				var root = element.getRootNode();
11205				return root instanceof ShadowRoot ? root : null;
11206			}
11207
11208			if (element instanceof ShadowRoot) {
11209				return element;
11210			} // when we don't find a shadow root
11211
11212
11213			if (!element.parentNode) {
11214				return null;
11215			}
11216
11217			return Util.findShadowRoot(element.parentNode);
11218		},
11219		jQueryDetection: function jQueryDetection() {
11220			if (typeof $__default['default'] === 'undefined') {
11221				throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
11222			}
11223
11224			var version = $__default['default'].fn.jquery.split(' ')[0].split('.');
11225			var minMajor = 1;
11226			var ltMajor = 2;
11227			var minMinor = 9;
11228			var minPatch = 1;
11229			var maxMajor = 4;
11230
11231			if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
11232				throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
11233			}
11234		}
11235	};
11236	Util.jQueryDetection();
11237	setTransitionEndSupport();
11238
11239	/**
11240	 * ------------------------------------------------------------------------
11241	 * Constants
11242	 * ------------------------------------------------------------------------
11243	 */
11244
11245	var NAME = 'alert';
11246	var VERSION = '4.5.3';
11247	var DATA_KEY = 'bs.alert';
11248	var EVENT_KEY = "." + DATA_KEY;
11249	var DATA_API_KEY = '.data-api';
11250	var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME];
11251	var SELECTOR_DISMISS = '[data-dismiss="alert"]';
11252	var EVENT_CLOSE = "close" + EVENT_KEY;
11253	var EVENT_CLOSED = "closed" + EVENT_KEY;
11254	var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
11255	var CLASS_NAME_ALERT = 'alert';
11256	var CLASS_NAME_FADE = 'fade';
11257	var CLASS_NAME_SHOW = 'show';
11258	/**
11259	 * ------------------------------------------------------------------------
11260	 * Class Definition
11261	 * ------------------------------------------------------------------------
11262	 */
11263
11264	var Alert = /*#__PURE__*/function () {
11265		function Alert(element) {
11266			this._element = element;
11267		} // Getters
11268
11269
11270		var _proto = Alert.prototype;
11271
11272		// Public
11273		_proto.close = function close(element) {
11274			var rootElement = this._element;
11275
11276			if (element) {
11277				rootElement = this._getRootElement(element);
11278			}
11279
11280			var customEvent = this._triggerCloseEvent(rootElement);
11281
11282			if (customEvent.isDefaultPrevented()) {
11283				return;
11284			}
11285
11286			this._removeElement(rootElement);
11287		};
11288
11289		_proto.dispose = function dispose() {
11290			$__default['default'].removeData(this._element, DATA_KEY);
11291			this._element = null;
11292		} // Private
11293		;
11294
11295		_proto._getRootElement = function _getRootElement(element) {
11296			var selector = Util.getSelectorFromElement(element);
11297			var parent = false;
vendor: 11,226 bytes, lines 11298-11655
11298
11299			if (selector) {
11300				parent = document.querySelector(selector);
11301			}
11302
11303			if (!parent) {
11304				parent = $__default['default'](element).closest("." + CLASS_NAME_ALERT)[0];
11305			}
11306
11307			return parent;
11308		};
11309
11310		_proto._triggerCloseEvent = function _triggerCloseEvent(element) {
11311			var closeEvent = $__default['default'].Event(EVENT_CLOSE);
11312			$__default['default'](element).trigger(closeEvent);
11313			return closeEvent;
11314		};
11315
11316		_proto._removeElement = function _removeElement(element) {
11317			var _this = this;
11318
11319			$__default['default'](element).removeClass(CLASS_NAME_SHOW);
11320
11321			if (!$__default['default'](element).hasClass(CLASS_NAME_FADE)) {
11322				this._destroyElement(element);
11323
11324				return;
11325			}
11326
11327			var transitionDuration = Util.getTransitionDurationFromElement(element);
11328			$__default['default'](element).one(Util.TRANSITION_END, function (event) {
11329				return _this._destroyElement(element, event);
11330			}).emulateTransitionEnd(transitionDuration);
11331		};
11332
11333		_proto._destroyElement = function _destroyElement(element) {
11334			$__default['default'](element).detach().trigger(EVENT_CLOSED).remove();
11335		} // Static
11336		;
11337
11338		Alert._jQueryInterface = function _jQueryInterface(config) {
11339			return this.each(function () {
11340				var $element = $__default['default'](this);
11341				var data = $element.data(DATA_KEY);
11342
11343				if (!data) {
11344					data = new Alert(this);
11345					$element.data(DATA_KEY, data);
11346				}
11347
11348				if (config === 'close') {
11349					data[config](this);
11350				}
11351			});
11352		};
11353
11354		Alert._handleDismiss = function _handleDismiss(alertInstance) {
11355			return function (event) {
11356				if (event) {
11357					event.preventDefault();
11358				}
11359
11360				alertInstance.close(this);
11361			};
11362		};
11363
11364		_createClass(Alert, null, [{
11365			key: "VERSION",
11366			get: function get() {
11367				return VERSION;
11368			}
11369		}]);
11370
11371		return Alert;
11372	}();
11373	/**
11374	 * ------------------------------------------------------------------------
11375	 * Data Api implementation
11376	 * ------------------------------------------------------------------------
11377	 */
11378
11379
11380	$__default['default'](document).on(EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert._handleDismiss(new Alert()));
11381	/**
11382	 * ------------------------------------------------------------------------
11383	 * jQuery
11384	 * ------------------------------------------------------------------------
11385	 */
11386
11387	$__default['default'].fn[NAME] = Alert._jQueryInterface;
11388	$__default['default'].fn[NAME].Constructor = Alert;
11389
11390	$__default['default'].fn[NAME].noConflict = function () {
11391		$__default['default'].fn[NAME] = JQUERY_NO_CONFLICT;
11392		return Alert._jQueryInterface;
11393	};
11394
11395	/**
11396	 * ------------------------------------------------------------------------
11397	 * Constants
11398	 * ------------------------------------------------------------------------
11399	 */
11400
11401	var NAME$1 = 'button';
11402	var VERSION$1 = '4.5.3';
11403	var DATA_KEY$1 = 'bs.button';
11404	var EVENT_KEY$1 = "." + DATA_KEY$1;
11405	var DATA_API_KEY$1 = '.data-api';
11406	var JQUERY_NO_CONFLICT$1 = $__default['default'].fn[NAME$1];
11407	var CLASS_NAME_ACTIVE = 'active';
11408	var CLASS_NAME_BUTTON = 'btn';
11409	var CLASS_NAME_FOCUS = 'focus';
11410	var SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]';
11411	var SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]';
11412	var SELECTOR_DATA_TOGGLE = '[data-toggle="button"]';
11413	var SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn';
11414	var SELECTOR_INPUT = 'input:not([type="hidden"])';
11415	var SELECTOR_ACTIVE = '.active';
11416	var SELECTOR_BUTTON = '.btn';
11417	var EVENT_CLICK_DATA_API$1 = "click" + EVENT_KEY$1 + DATA_API_KEY$1;
11418	var EVENT_FOCUS_BLUR_DATA_API = "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1);
11419	var EVENT_LOAD_DATA_API = "load" + EVENT_KEY$1 + DATA_API_KEY$1;
11420	/**
11421	 * ------------------------------------------------------------------------
11422	 * Class Definition
11423	 * ------------------------------------------------------------------------
11424	 */
11425
11426	var Button = /*#__PURE__*/function () {
11427		function Button(element) {
11428			this._element = element;
11429			this.shouldAvoidTriggerChange = false;
11430		} // Getters
11431
11432
11433		var _proto = Button.prototype;
11434
11435		// Public
11436		_proto.toggle = function toggle() {
11437			var triggerChangeEvent = true;
11438			var addAriaPressed = true;
11439			var rootElement = $__default['default'](this._element).closest(SELECTOR_DATA_TOGGLES)[0];
11440
11441			if (rootElement) {
11442				var input = this._element.querySelector(SELECTOR_INPUT);
11443
11444				if (input) {
11445					if (input.type === 'radio') {
11446						if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {
11447							triggerChangeEvent = false;
11448						} else {
11449							var activeElement = rootElement.querySelector(SELECTOR_ACTIVE);
11450
11451							if (activeElement) {
11452								$__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE);
11453							}
11454						}
11455					}
11456
11457					if (triggerChangeEvent) {
11458						// if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
11459						if (input.type === 'checkbox' || input.type === 'radio') {
11460							input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE);
11461						}
11462
11463						if (!this.shouldAvoidTriggerChange) {
11464							$__default['default'](input).trigger('change');
11465						}
11466					}
11467
11468					input.focus();
11469					addAriaPressed = false;
11470				}
11471			}
11472
11473			if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
11474				if (addAriaPressed) {
11475					this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE));
11476				}
11477
11478				if (triggerChangeEvent) {
11479					$__default['default'](this._element).toggleClass(CLASS_NAME_ACTIVE);
11480				}
11481			}
11482		};
11483
11484		_proto.dispose = function dispose() {
11485			$__default['default'].removeData(this._element, DATA_KEY$1);
11486			this._element = null;
11487		} // Static
11488		;
11489
11490		Button._jQueryInterface = function _jQueryInterface(config, avoidTriggerChange) {
11491			return this.each(function () {
11492				var $element = $__default['default'](this);
11493				var data = $element.data(DATA_KEY$1);
11494
11495				if (!data) {
11496					data = new Button(this);
11497					$element.data(DATA_KEY$1, data);
11498				}
11499
11500				data.shouldAvoidTriggerChange = avoidTriggerChange;
11501
11502				if (config === 'toggle') {
11503					data[config]();
11504				}
11505			});
11506		};
11507
11508		_createClass(Button, null, [{
11509			key: "VERSION",
11510			get: function get() {
11511				return VERSION$1;
11512			}
11513		}]);
11514
11515		return Button;
11516	}();
11517	/**
11518	 * ------------------------------------------------------------------------
11519	 * Data Api implementation
11520	 * ------------------------------------------------------------------------
11521	 */
11522
11523
11524	$__default['default'](document).on(EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
11525		var button = event.target;
11526		var initialButton = button;
11527
11528		if (!$__default['default'](button).hasClass(CLASS_NAME_BUTTON)) {
11529			button = $__default['default'](button).closest(SELECTOR_BUTTON)[0];
11530		}
11531
11532		if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
11533			event.preventDefault(); // work around Firefox bug #1540995
11534		} else {
11535			var inputBtn = button.querySelector(SELECTOR_INPUT);
11536
11537			if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
11538				event.preventDefault(); // work around Firefox bug #1540995
11539
11540				return;
11541			}
11542
11543			if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {
11544				Button._jQueryInterface.call($__default['default'](button), 'toggle', initialButton.tagName === 'INPUT');
11545			}
11546		}
11547	}).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
11548		var button = $__default['default'](event.target).closest(SELECTOR_BUTTON)[0];
11549		$__default['default'](button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type));
11550	});
11551	$__default['default'](window).on(EVENT_LOAD_DATA_API, function () {
11552		// ensure correct active class is set to match the controls' actual values/states
11553		// find all checkboxes/readio buttons inside data-toggle groups
11554		var buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS));
11555
11556		for (var i = 0, len = buttons.length; i < len; i++) {
11557			var button = buttons[i];
11558			var input = button.querySelector(SELECTOR_INPUT);
11559
11560			if (input.checked || input.hasAttribute('checked')) {
11561				button.classList.add(CLASS_NAME_ACTIVE);
11562			} else {
11563				button.classList.remove(CLASS_NAME_ACTIVE);
11564			}
11565		} // find all button toggles
11566
11567
11568		buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
11569
11570		for (var _i = 0, _len = buttons.length; _i < _len; _i++) {
11571			var _button = buttons[_i];
11572
11573			if (_button.getAttribute('aria-pressed') === 'true') {
11574				_button.classList.add(CLASS_NAME_ACTIVE);
11575			} else {
11576				_button.classList.remove(CLASS_NAME_ACTIVE);
11577			}
11578		}
11579	});
11580	/**
11581	 * ------------------------------------------------------------------------
11582	 * jQuery
11583	 * ------------------------------------------------------------------------
11584	 */
11585
11586	$__default['default'].fn[NAME$1] = Button._jQueryInterface;
11587	$__default['default'].fn[NAME$1].Constructor = Button;
11588
11589	$__default['default'].fn[NAME$1].noConflict = function () {
11590		$__default['default'].fn[NAME$1] = JQUERY_NO_CONFLICT$1;
11591		return Button._jQueryInterface;
11592	};
11593
11594	/**
11595	 * ------------------------------------------------------------------------
11596	 * Constants
11597	 * ------------------------------------------------------------------------
11598	 */
11599
11600	var NAME$2 = 'carousel';
11601	var VERSION$2 = '4.5.3';
11602	var DATA_KEY$2 = 'bs.carousel';
11603	var EVENT_KEY$2 = "." + DATA_KEY$2;
11604	var DATA_API_KEY$2 = '.data-api';
11605	var JQUERY_NO_CONFLICT$2 = $__default['default'].fn[NAME$2];
11606	var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
11607
11608	var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
11609
11610	var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
11611
11612	var SWIPE_THRESHOLD = 40;
11613	var Default = {
11614		interval: 5000,
11615		keyboard: true,
11616		slide: false,
11617		pause: 'hover',
11618		wrap: true,
11619		touch: true
11620	};
11621	var DefaultType = {
11622		interval: '(number|boolean)',
11623		keyboard: 'boolean',
11624		slide: '(boolean|string)',
11625		pause: '(string|boolean)',
11626		wrap: 'boolean',
11627		touch: 'boolean'
11628	};
11629	var DIRECTION_NEXT = 'next';
11630	var DIRECTION_PREV = 'prev';
11631	var DIRECTION_LEFT = 'left';
11632	var DIRECTION_RIGHT = 'right';
11633	var EVENT_SLIDE = "slide" + EVENT_KEY$2;
11634	var EVENT_SLID = "slid" + EVENT_KEY$2;
11635	var EVENT_KEYDOWN = "keydown" + EVENT_KEY$2;
11636	var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY$2;
11637	var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY$2;
11638	var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY$2;
11639	var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY$2;
11640	var EVENT_TOUCHEND = "touchend" + EVENT_KEY$2;
11641	var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY$2;
11642	var EVENT_POINTERUP = "pointerup" + EVENT_KEY$2;
11643	var EVENT_DRAG_START = "dragstart" + EVENT_KEY$2;
11644	var EVENT_LOAD_DATA_API$1 = "load" + EVENT_KEY$2 + DATA_API_KEY$2;
11645	var EVENT_CLICK_DATA_API$2 = "click" + EVENT_KEY$2 + DATA_API_KEY$2;
11646	var CLASS_NAME_CAROUSEL = 'carousel';
11647	var CLASS_NAME_ACTIVE$1 = 'active';
11648	var CLASS_NAME_SLIDE = 'slide';
11649	var CLASS_NAME_RIGHT = 'carousel-item-right';
11650	var CLASS_NAME_LEFT = 'carousel-item-left';
11651	var CLASS_NAME_NEXT = 'carousel-item-next';
11652	var CLASS_NAME_PREV = 'carousel-item-prev';
11653	var CLASS_NAME_POINTER_EVENT = 'pointer-event';
11654	var SELECTOR_ACTIVE$1 = '.active';
11655	var SELECTOR_ACTIVE_ITEM = '.active.carousel-item';
vendor: 10,453 bytes, lines 11656-12009
11656	var SELECTOR_ITEM = '.carousel-item';
11657	var SELECTOR_ITEM_IMG = '.carousel-item img';
11658	var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';
11659	var SELECTOR_INDICATORS = '.carousel-indicators';
11660	var SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]';
11661	var SELECTOR_DATA_RIDE = '[data-ride="carousel"]';
11662	var PointerType = {
11663		TOUCH: 'touch',
11664		PEN: 'pen'
11665	};
11666	/**
11667	 * ------------------------------------------------------------------------
11668	 * Class Definition
11669	 * ------------------------------------------------------------------------
11670	 */
11671
11672	var Carousel = /*#__PURE__*/function () {
11673		function Carousel(element, config) {
11674			this._items = null;
11675			this._interval = null;
11676			this._activeElement = null;
11677			this._isPaused = false;
11678			this._isSliding = false;
11679			this.touchTimeout = null;
11680			this.touchStartX = 0;
11681			this.touchDeltaX = 0;
11682			this._config = this._getConfig(config);
11683			this._element = element;
11684			this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS);
11685			this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
11686			this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
11687
11688			this._addEventListeners();
11689		} // Getters
11690
11691
11692		var _proto = Carousel.prototype;
11693
11694		// Public
11695		_proto.next = function next() {
11696			if (!this._isSliding) {
11697				this._slide(DIRECTION_NEXT);
11698			}
11699		};
11700
11701		_proto.nextWhenVisible = function nextWhenVisible() {
11702			var $element = $__default['default'](this._element); // Don't call next when the page isn't visible
11703			// or the carousel or its parent isn't visible
11704
11705			if (!document.hidden && $element.is(':visible') && $element.css('visibility') !== 'hidden') {
11706				this.next();
11707			}
11708		};
11709
11710		_proto.prev = function prev() {
11711			if (!this._isSliding) {
11712				this._slide(DIRECTION_PREV);
11713			}
11714		};
11715
11716		_proto.pause = function pause(event) {
11717			if (!event) {
11718				this._isPaused = true;
11719			}
11720
11721			if (this._element.querySelector(SELECTOR_NEXT_PREV)) {
11722				Util.triggerTransitionEnd(this._element);
11723				this.cycle(true);
11724			}
11725
11726			clearInterval(this._interval);
11727			this._interval = null;
11728		};
11729
11730		_proto.cycle = function cycle(event) {
11731			if (!event) {
11732				this._isPaused = false;
11733			}
11734
11735			if (this._interval) {
11736				clearInterval(this._interval);
11737				this._interval = null;
11738			}
11739
11740			if (this._config.interval && !this._isPaused) {
11741				this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
11742			}
11743		};
11744
11745		_proto.to = function to(index) {
11746			var _this = this;
11747
11748			this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
11749
11750			var activeIndex = this._getItemIndex(this._activeElement);
11751
11752			if (index > this._items.length - 1 || index < 0) {
11753				return;
11754			}
11755
11756			if (this._isSliding) {
11757				$__default['default'](this._element).one(EVENT_SLID, function () {
11758					return _this.to(index);
11759				});
11760				return;
11761			}
11762
11763			if (activeIndex === index) {
11764				this.pause();
11765				this.cycle();
11766				return;
11767			}
11768
11769			var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV;
11770
11771			this._slide(direction, this._items[index]);
11772		};
11773
11774		_proto.dispose = function dispose() {
11775			$__default['default'](this._element).off(EVENT_KEY$2);
11776			$__default['default'].removeData(this._element, DATA_KEY$2);
11777			this._items = null;
11778			this._config = null;
11779			this._element = null;
11780			this._interval = null;
11781			this._isPaused = null;
11782			this._isSliding = null;
11783			this._activeElement = null;
11784			this._indicatorsElement = null;
11785		} // Private
11786		;
11787
11788		_proto._getConfig = function _getConfig(config) {
11789			config = _extends({}, Default, config);
11790			Util.typeCheckConfig(NAME$2, config, DefaultType);
11791			return config;
11792		};
11793
11794		_proto._handleSwipe = function _handleSwipe() {
11795			var absDeltax = Math.abs(this.touchDeltaX);
11796
11797			if (absDeltax <= SWIPE_THRESHOLD) {
11798				return;
11799			}
11800
11801			var direction = absDeltax / this.touchDeltaX;
11802			this.touchDeltaX = 0; // swipe left
11803
11804			if (direction > 0) {
11805				this.prev();
11806			} // swipe right
11807
11808
11809			if (direction < 0) {
11810				this.next();
11811			}
11812		};
11813
11814		_proto._addEventListeners = function _addEventListeners() {
11815			var _this2 = this;
11816
11817			if (this._config.keyboard) {
11818				$__default['default'](this._element).on(EVENT_KEYDOWN, function (event) {
11819					return _this2._keydown(event);
11820				});
11821			}
11822
11823			if (this._config.pause === 'hover') {
11824				$__default['default'](this._element).on(EVENT_MOUSEENTER, function (event) {
11825					return _this2.pause(event);
11826				}).on(EVENT_MOUSELEAVE, function (event) {
11827					return _this2.cycle(event);
11828				});
11829			}
11830
11831			if (this._config.touch) {
11832				this._addTouchEventListeners();
11833			}
11834		};
11835
11836		_proto._addTouchEventListeners = function _addTouchEventListeners() {
11837			var _this3 = this;
11838
11839			if (!this._touchSupported) {
11840				return;
11841			}
11842
11843			var start = function start(event) {
11844				if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
11845					_this3.touchStartX = event.originalEvent.clientX;
11846				} else if (!_this3._pointerEvent) {
11847					_this3.touchStartX = event.originalEvent.touches[0].clientX;
11848				}
11849			};
11850
11851			var move = function move(event) {
11852				// ensure swiping with one touch and not pinching
11853				if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {
11854					_this3.touchDeltaX = 0;
11855				} else {
11856					_this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX;
11857				}
11858			};
11859
11860			var end = function end(event) {
11861				if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
11862					_this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;
11863				}
11864
11865				_this3._handleSwipe();
11866
11867				if (_this3._config.pause === 'hover') {
11868					// If it's a touch-enabled device, mouseenter/leave are fired as
11869					// part of the mouse compatibility events on first tap - the carousel
11870					// would stop cycling until user tapped out of it;
11871					// here, we listen for touchend, explicitly pause the carousel
11872					// (as if it's the second time we tap on it, mouseenter compat event
11873					// is NOT fired) and after a timeout (to allow for mouse compatibility
11874					// events to fire) we explicitly restart cycling
11875					_this3.pause();
11876
11877					if (_this3.touchTimeout) {
11878						clearTimeout(_this3.touchTimeout);
11879					}
11880
11881					_this3.touchTimeout = setTimeout(function (event) {
11882						return _this3.cycle(event);
11883					}, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);
11884				}
11885			};
11886
11887			$__default['default'](this._element.querySelectorAll(SELECTOR_ITEM_IMG)).on(EVENT_DRAG_START, function (e) {
11888				return e.preventDefault();
11889			});
11890
11891			if (this._pointerEvent) {
11892				$__default['default'](this._element).on(EVENT_POINTERDOWN, function (event) {
11893					return start(event);
11894				});
11895				$__default['default'](this._element).on(EVENT_POINTERUP, function (event) {
11896					return end(event);
11897				});
11898
11899				this._element.classList.add(CLASS_NAME_POINTER_EVENT);
11900			} else {
11901				$__default['default'](this._element).on(EVENT_TOUCHSTART, function (event) {
11902					return start(event);
11903				});
11904				$__default['default'](this._element).on(EVENT_TOUCHMOVE, function (event) {
11905					return move(event);
11906				});
11907				$__default['default'](this._element).on(EVENT_TOUCHEND, function (event) {
11908					return end(event);
11909				});
11910			}
11911		};
11912
11913		_proto._keydown = function _keydown(event) {
11914			if (/input|textarea/i.test(event.target.tagName)) {
11915				return;
11916			}
11917
11918			switch (event.which) {
11919				case ARROW_LEFT_KEYCODE:
11920					event.preventDefault();
11921					this.prev();
11922					break;
11923
11924				case ARROW_RIGHT_KEYCODE:
11925					event.preventDefault();
11926					this.next();
11927					break;
11928			}
11929		};
11930
11931		_proto._getItemIndex = function _getItemIndex(element) {
11932			this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : [];
11933			return this._items.indexOf(element);
11934		};
11935
11936		_proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
11937			var isNextDirection = direction === DIRECTION_NEXT;
11938			var isPrevDirection = direction === DIRECTION_PREV;
11939
11940			var activeIndex = this._getItemIndex(activeElement);
11941
11942			var lastItemIndex = this._items.length - 1;
11943			var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
11944
11945			if (isGoingToWrap && !this._config.wrap) {
11946				return activeElement;
11947			}
11948
11949			var delta = direction === DIRECTION_PREV ? -1 : 1;
11950			var itemIndex = (activeIndex + delta) % this._items.length;
11951			return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
11952		};
11953
11954		_proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
11955			var targetIndex = this._getItemIndex(relatedTarget);
11956
11957			var fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM));
11958
11959			var slideEvent = $__default['default'].Event(EVENT_SLIDE, {
11960				relatedTarget: relatedTarget,
11961				direction: eventDirectionName,
11962				from: fromIndex,
11963				to: targetIndex
11964			});
11965			$__default['default'](this._element).trigger(slideEvent);
11966			return slideEvent;
11967		};
11968
11969		_proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
11970			if (this._indicatorsElement) {
11971				var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE$1));
11972				$__default['default'](indicators).removeClass(CLASS_NAME_ACTIVE$1);
11973
11974				var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
11975
11976				if (nextIndicator) {
11977					$__default['default'](nextIndicator).addClass(CLASS_NAME_ACTIVE$1);
11978				}
11979			}
11980		};
11981
11982		_proto._slide = function _slide(direction, element) {
11983			var _this4 = this;
11984
11985			var activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
11986
11987			var activeElementIndex = this._getItemIndex(activeElement);
11988
11989			var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
11990
11991			var nextElementIndex = this._getItemIndex(nextElement);
11992
11993			var isCycling = Boolean(this._interval);
11994			var directionalClassName;
11995			var orderClassName;
11996			var eventDirectionName;
11997
11998			if (direction === DIRECTION_NEXT) {
11999				directionalClassName = CLASS_NAME_LEFT;
12000				orderClassName = CLASS_NAME_NEXT;
12001				eventDirectionName = DIRECTION_LEFT;
12002			} else {
12003				directionalClassName = CLASS_NAME_RIGHT;
12004				orderClassName = CLASS_NAME_PREV;
12005				eventDirectionName = DIRECTION_RIGHT;
12006			}
12007
12008			if (nextElement && $__default['default'](nextElement).hasClass(CLASS_NAME_ACTIVE$1)) {
12009				this._isSliding = false;
vendor: 4,587 bytes, lines 12010-12164
12010				return;
12011			}
12012
12013			var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
12014
12015			if (slideEvent.isDefaultPrevented()) {
12016				return;
12017			}
12018
12019			if (!activeElement || !nextElement) {
12020				// Some weirdness is happening, so we bail
12021				return;
12022			}
12023
12024			this._isSliding = true;
12025
12026			if (isCycling) {
12027				this.pause();
12028			}
12029
12030			this._setActiveIndicatorElement(nextElement);
12031
12032			var slidEvent = $__default['default'].Event(EVENT_SLID, {
12033				relatedTarget: nextElement,
12034				direction: eventDirectionName,
12035				from: activeElementIndex,
12036				to: nextElementIndex
12037			});
12038
12039			if ($__default['default'](this._element).hasClass(CLASS_NAME_SLIDE)) {
12040				$__default['default'](nextElement).addClass(orderClassName);
12041				Util.reflow(nextElement);
12042				$__default['default'](activeElement).addClass(directionalClassName);
12043				$__default['default'](nextElement).addClass(directionalClassName);
12044				var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10);
12045
12046				if (nextElementInterval) {
12047					this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
12048					this._config.interval = nextElementInterval;
12049				} else {
12050					this._config.interval = this._config.defaultInterval || this._config.interval;
12051				}
12052
12053				var transitionDuration = Util.getTransitionDurationFromElement(activeElement);
12054				$__default['default'](activeElement).one(Util.TRANSITION_END, function () {
12055					$__default['default'](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE$1);
12056					$__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE$1 + " " + orderClassName + " " + directionalClassName);
12057					_this4._isSliding = false;
12058					setTimeout(function () {
12059						return $__default['default'](_this4._element).trigger(slidEvent);
12060					}, 0);
12061				}).emulateTransitionEnd(transitionDuration);
12062			} else {
12063				$__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE$1);
12064				$__default['default'](nextElement).addClass(CLASS_NAME_ACTIVE$1);
12065				this._isSliding = false;
12066				$__default['default'](this._element).trigger(slidEvent);
12067			}
12068
12069			if (isCycling) {
12070				this.cycle();
12071			}
12072		} // Static
12073		;
12074
12075		Carousel._jQueryInterface = function _jQueryInterface(config) {
12076			return this.each(function () {
12077				var data = $__default['default'](this).data(DATA_KEY$2);
12078
12079				var _config = _extends({}, Default, $__default['default'](this).data());
12080
12081				if (typeof config === 'object') {
12082					_config = _extends({}, _config, config);
12083				}
12084
12085				var action = typeof config === 'string' ? config : _config.slide;
12086
12087				if (!data) {
12088					data = new Carousel(this, _config);
12089					$__default['default'](this).data(DATA_KEY$2, data);
12090				}
12091
12092				if (typeof config === 'number') {
12093					data.to(config);
12094				} else if (typeof action === 'string') {
12095					if (typeof data[action] === 'undefined') {
12096						throw new TypeError("No method named \"" + action + "\"");
12097					}
12098
12099					data[action]();
12100				} else if (_config.interval && _config.ride) {
12101					data.pause();
12102					data.cycle();
12103				}
12104			});
12105		};
12106
12107		Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
12108			var selector = Util.getSelectorFromElement(this);
12109
12110			if (!selector) {
12111				return;
12112			}
12113
12114			var target = $__default['default'](selector)[0];
12115
12116			if (!target || !$__default['default'](target).hasClass(CLASS_NAME_CAROUSEL)) {
12117				return;
12118			}
12119
12120			var config = _extends({}, $__default['default'](target).data(), $__default['default'](this).data());
12121
12122			var slideIndex = this.getAttribute('data-slide-to');
12123
12124			if (slideIndex) {
12125				config.interval = false;
12126			}
12127
12128			Carousel._jQueryInterface.call($__default['default'](target), config);
12129
12130			if (slideIndex) {
12131				$__default['default'](target).data(DATA_KEY$2).to(slideIndex);
12132			}
12133
12134			event.preventDefault();
12135		};
12136
12137		_createClass(Carousel, null, [{
12138			key: "VERSION",
12139			get: function get() {
12140				return VERSION$2;
12141			}
12142		}, {
12143			key: "Default",
12144			get: function get() {
12145				return Default;
12146			}
12147		}]);
12148
12149		return Carousel;
12150	}();
12151	/**
12152	 * ------------------------------------------------------------------------
12153	 * Data Api implementation
12154	 * ------------------------------------------------------------------------
12155	 */
12156
12157
12158	$__default['default'](document).on(EVENT_CLICK_DATA_API$2, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler);
12159	$__default['default'](window).on(EVENT_LOAD_DATA_API$1, function () {
12160		var carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE));
12161
12162		for (var i = 0, len = carousels.length; i < len; i++) {
12163			var $carousel = $__default['default'](carousels[i]);
12164
vendor: 9,657 bytes, lines 12165-12461
12165			Carousel._jQueryInterface.call($carousel, $carousel.data());
12166		}
12167	});
12168	/**
12169	 * ------------------------------------------------------------------------
12170	 * jQuery
12171	 * ------------------------------------------------------------------------
12172	 */
12173
12174	$__default['default'].fn[NAME$2] = Carousel._jQueryInterface;
12175	$__default['default'].fn[NAME$2].Constructor = Carousel;
12176
12177	$__default['default'].fn[NAME$2].noConflict = function () {
12178		$__default['default'].fn[NAME$2] = JQUERY_NO_CONFLICT$2;
12179		return Carousel._jQueryInterface;
12180	};
12181
12182	/**
12183	 * ------------------------------------------------------------------------
12184	 * Constants
12185	 * ------------------------------------------------------------------------
12186	 */
12187
12188	var NAME$3 = 'collapse';
12189	var VERSION$3 = '4.5.3';
12190	var DATA_KEY$3 = 'bs.collapse';
12191	var EVENT_KEY$3 = "." + DATA_KEY$3;
12192	var DATA_API_KEY$3 = '.data-api';
12193	var JQUERY_NO_CONFLICT$3 = $__default['default'].fn[NAME$3];
12194	var Default$1 = {
12195		toggle: true,
12196		parent: ''
12197	};
12198	var DefaultType$1 = {
12199		toggle: 'boolean',
12200		parent: '(string|element)'
12201	};
12202	var EVENT_SHOW = "show" + EVENT_KEY$3;
12203	var EVENT_SHOWN = "shown" + EVENT_KEY$3;
12204	var EVENT_HIDE = "hide" + EVENT_KEY$3;
12205	var EVENT_HIDDEN = "hidden" + EVENT_KEY$3;
12206	var EVENT_CLICK_DATA_API$3 = "click" + EVENT_KEY$3 + DATA_API_KEY$3;
12207	var CLASS_NAME_SHOW$1 = 'show';
12208	var CLASS_NAME_COLLAPSE = 'collapse';
12209	var CLASS_NAME_COLLAPSING = 'collapsing';
12210	var CLASS_NAME_COLLAPSED = 'collapsed';
12211	var DIMENSION_WIDTH = 'width';
12212	var DIMENSION_HEIGHT = 'height';
12213	var SELECTOR_ACTIVES = '.show, .collapsing';
12214	var SELECTOR_DATA_TOGGLE$1 = '[data-toggle="collapse"]';
12215	/**
12216	 * ------------------------------------------------------------------------
12217	 * Class Definition
12218	 * ------------------------------------------------------------------------
12219	 */
12220
12221	var Collapse = /*#__PURE__*/function () {
12222		function Collapse(element, config) {
12223			this._isTransitioning = false;
12224			this._element = element;
12225			this._config = this._getConfig(config);
12226			this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
12227			var toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$1));
12228
12229			for (var i = 0, len = toggleList.length; i < len; i++) {
12230				var elem = toggleList[i];
12231				var selector = Util.getSelectorFromElement(elem);
12232				var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {
12233					return foundElem === element;
12234				});
12235
12236				if (selector !== null && filterElement.length > 0) {
12237					this._selector = selector;
12238
12239					this._triggerArray.push(elem);
12240				}
12241			}
12242
12243			this._parent = this._config.parent ? this._getParent() : null;
12244
12245			if (!this._config.parent) {
12246				this._addAriaAndCollapsedClass(this._element, this._triggerArray);
12247			}
12248
12249			if (this._config.toggle) {
12250				this.toggle();
12251			}
12252		} // Getters
12253
12254
12255		var _proto = Collapse.prototype;
12256
12257		// Public
12258		_proto.toggle = function toggle() {
12259			if ($__default['default'](this._element).hasClass(CLASS_NAME_SHOW$1)) {
12260				this.hide();
12261			} else {
12262				this.show();
12263			}
12264		};
12265
12266		_proto.show = function show() {
12267			var _this = this;
12268
12269			if (this._isTransitioning || $__default['default'](this._element).hasClass(CLASS_NAME_SHOW$1)) {
12270				return;
12271			}
12272
12273			var actives;
12274			var activesData;
12275
12276			if (this._parent) {
12277				actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)).filter(function (elem) {
12278					if (typeof _this._config.parent === 'string') {
12279						return elem.getAttribute('data-parent') === _this._config.parent;
12280					}
12281
12282					return elem.classList.contains(CLASS_NAME_COLLAPSE);
12283				});
12284
12285				if (actives.length === 0) {
12286					actives = null;
12287				}
12288			}
12289
12290			if (actives) {
12291				activesData = $__default['default'](actives).not(this._selector).data(DATA_KEY$3);
12292
12293				if (activesData && activesData._isTransitioning) {
12294					return;
12295				}
12296			}
12297
12298			var startEvent = $__default['default'].Event(EVENT_SHOW);
12299			$__default['default'](this._element).trigger(startEvent);
12300
12301			if (startEvent.isDefaultPrevented()) {
12302				return;
12303			}
12304
12305			if (actives) {
12306				Collapse._jQueryInterface.call($__default['default'](actives).not(this._selector), 'hide');
12307
12308				if (!activesData) {
12309					$__default['default'](actives).data(DATA_KEY$3, null);
12310				}
12311			}
12312
12313			var dimension = this._getDimension();
12314
12315			$__default['default'](this._element).removeClass(CLASS_NAME_COLLAPSE).addClass(CLASS_NAME_COLLAPSING);
12316			this._element.style[dimension] = 0;
12317
12318			if (this._triggerArray.length) {
12319				$__default['default'](this._triggerArray).removeClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', true);
12320			}
12321
12322			this.setTransitioning(true);
12323
12324			var complete = function complete() {
12325				$__default['default'](_this._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$1);
12326				_this._element.style[dimension] = '';
12327
12328				_this.setTransitioning(false);
12329
12330				$__default['default'](_this._element).trigger(EVENT_SHOWN);
12331			};
12332
12333			var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
12334			var scrollSize = "scroll" + capitalizedDimension;
12335			var transitionDuration = Util.getTransitionDurationFromElement(this._element);
12336			$__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
12337			this._element.style[dimension] = this._element[scrollSize] + "px";
12338		};
12339
12340		_proto.hide = function hide() {
12341			var _this2 = this;
12342
12343			if (this._isTransitioning || !$__default['default'](this._element).hasClass(CLASS_NAME_SHOW$1)) {
12344				return;
12345			}
12346
12347			var startEvent = $__default['default'].Event(EVENT_HIDE);
12348			$__default['default'](this._element).trigger(startEvent);
12349
12350			if (startEvent.isDefaultPrevented()) {
12351				return;
12352			}
12353
12354			var dimension = this._getDimension();
12355
12356			this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
12357			Util.reflow(this._element);
12358			$__default['default'](this._element).addClass(CLASS_NAME_COLLAPSING).removeClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$1);
12359			var triggerArrayLength = this._triggerArray.length;
12360
12361			if (triggerArrayLength > 0) {
12362				for (var i = 0; i < triggerArrayLength; i++) {
12363					var trigger = this._triggerArray[i];
12364					var selector = Util.getSelectorFromElement(trigger);
12365
12366					if (selector !== null) {
12367						var $elem = $__default['default']([].slice.call(document.querySelectorAll(selector)));
12368
12369						if (!$elem.hasClass(CLASS_NAME_SHOW$1)) {
12370							$__default['default'](trigger).addClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', false);
12371						}
12372					}
12373				}
12374			}
12375
12376			this.setTransitioning(true);
12377
12378			var complete = function complete() {
12379				_this2.setTransitioning(false);
12380
12381				$__default['default'](_this2._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE).trigger(EVENT_HIDDEN);
12382			};
12383
12384			this._element.style[dimension] = '';
12385			var transitionDuration = Util.getTransitionDurationFromElement(this._element);
12386			$__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
12387		};
12388
12389		_proto.setTransitioning = function setTransitioning(isTransitioning) {
12390			this._isTransitioning = isTransitioning;
12391		};
12392
12393		_proto.dispose = function dispose() {
12394			$__default['default'].removeData(this._element, DATA_KEY$3);
12395			this._config = null;
12396			this._parent = null;
12397			this._element = null;
12398			this._triggerArray = null;
12399			this._isTransitioning = null;
12400		} // Private
12401		;
12402
12403		_proto._getConfig = function _getConfig(config) {
12404			config = _extends({}, Default$1, config);
12405			config.toggle = Boolean(config.toggle); // Coerce string values
12406
12407			Util.typeCheckConfig(NAME$3, config, DefaultType$1);
12408			return config;
12409		};
12410
12411		_proto._getDimension = function _getDimension() {
12412			var hasWidth = $__default['default'](this._element).hasClass(DIMENSION_WIDTH);
12413			return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT;
12414		};
12415
12416		_proto._getParent = function _getParent() {
12417			var _this3 = this;
12418
12419			var parent;
12420
12421			if (Util.isElement(this._config.parent)) {
12422				parent = this._config.parent; // It's a jQuery object
12423
12424				if (typeof this._config.parent.jquery !== 'undefined') {
12425					parent = this._config.parent[0];
12426				}
12427			} else {
12428				parent = document.querySelector(this._config.parent);
12429			}
12430
12431			var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
12432			var children = [].slice.call(parent.querySelectorAll(selector));
12433			$__default['default'](children).each(function (i, element) {
12434				_this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
12435			});
12436			return parent;
12437		};
12438
12439		_proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
12440			var isOpen = $__default['default'](element).hasClass(CLASS_NAME_SHOW$1);
12441
12442			if (triggerArray.length) {
12443				$__default['default'](triggerArray).toggleClass(CLASS_NAME_COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
12444			}
12445		} // Static
12446		;
12447
12448		Collapse._getTargetFromElement = function _getTargetFromElement(element) {
12449			var selector = Util.getSelectorFromElement(element);
12450			return selector ? document.querySelector(selector) : null;
12451		};
12452
12453		Collapse._jQueryInterface = function _jQueryInterface(config) {
12454			return this.each(function () {
12455				var $element = $__default['default'](this);
12456				var data = $element.data(DATA_KEY$3);
12457
12458				var _config = _extends({}, Default$1, $element.data(), typeof config === 'object' && config ? config : {});
12459
12460				if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
12461					_config.toggle = false;
vendor: 6,529 bytes, lines 12462-12688
12462				}
12463
12464				if (!data) {
12465					data = new Collapse(this, _config);
12466					$element.data(DATA_KEY$3, data);
12467				}
12468
12469				if (typeof config === 'string') {
12470					if (typeof data[config] === 'undefined') {
12471						throw new TypeError("No method named \"" + config + "\"");
12472					}
12473
12474					data[config]();
12475				}
12476			});
12477		};
12478
12479		_createClass(Collapse, null, [{
12480			key: "VERSION",
12481			get: function get() {
12482				return VERSION$3;
12483			}
12484		}, {
12485			key: "Default",
12486			get: function get() {
12487				return Default$1;
12488			}
12489		}]);
12490
12491		return Collapse;
12492	}();
12493	/**
12494	 * ------------------------------------------------------------------------
12495	 * Data Api implementation
12496	 * ------------------------------------------------------------------------
12497	 */
12498
12499
12500	$__default['default'](document).on(EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$1, function (event) {
12501		// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
12502		if (event.currentTarget.tagName === 'A') {
12503			event.preventDefault();
12504		}
12505
12506		var $trigger = $__default['default'](this);
12507		var selector = Util.getSelectorFromElement(this);
12508		var selectors = [].slice.call(document.querySelectorAll(selector));
12509		$__default['default'](selectors).each(function () {
12510			var $target = $__default['default'](this);
12511			var data = $target.data(DATA_KEY$3);
12512			var config = data ? 'toggle' : $trigger.data();
12513
12514			Collapse._jQueryInterface.call($target, config);
12515		});
12516	});
12517	/**
12518	 * ------------------------------------------------------------------------
12519	 * jQuery
12520	 * ------------------------------------------------------------------------
12521	 */
12522
12523	$__default['default'].fn[NAME$3] = Collapse._jQueryInterface;
12524	$__default['default'].fn[NAME$3].Constructor = Collapse;
12525
12526	$__default['default'].fn[NAME$3].noConflict = function () {
12527		$__default['default'].fn[NAME$3] = JQUERY_NO_CONFLICT$3;
12528		return Collapse._jQueryInterface;
12529	};
12530
12531	/**!
12532	 * @fileOverview Kickass library to create and place poppers near their reference elements.
12533	 * @version 1.16.1
12534	 * @license
12535	 * Copyright (c) 2016 Federico Zivolo and contributors
12536	 *
12537	 * Permission is hereby granted, free of charge, to any person obtaining a copy
12538	 * of this software and associated documentation files (the "Software"), to deal
12539	 * in the Software without restriction, including without limitation the rights
12540	 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12541	 * copies of the Software, and to permit persons to whom the Software is
12542	 * furnished to do so, subject to the following conditions:
12543	 *
12544	 * The above copyright notice and this permission notice shall be included in all
12545	 * copies or substantial portions of the Software.
12546	 *
12547	 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12548	 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12549	 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12550	 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12551	 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12552	 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
12553	 * SOFTWARE.
12554	 */
12555	var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
12556
12557	var timeoutDuration = function () {
12558		var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
12559		for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
12560			if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
12561				return 1;
12562			}
12563		}
12564		return 0;
12565	}();
12566
12567	function microtaskDebounce(fn) {
12568		var called = false;
12569		return function () {
12570			if (called) {
12571				return;
12572			}
12573			called = true;
12574			window.Promise.resolve().then(function () {
12575				called = false;
12576				fn();
12577			});
12578		};
12579	}
12580
12581	function taskDebounce(fn) {
12582		var scheduled = false;
12583		return function () {
12584			if (!scheduled) {
12585				scheduled = true;
12586				setTimeout(function () {
12587					scheduled = false;
12588					fn();
12589				}, timeoutDuration);
12590			}
12591		};
12592	}
12593
12594	var supportsMicroTasks = isBrowser && window.Promise;
12595
12596	/**
12597	 * Create a debounced version of a method, that's asynchronously deferred
12598	 * but called in the minimum time possible.
12599	 *
12600	 * @method
12601	 * @memberof Popper.Utils
12602	 * @argument {Function} fn
12603	 * @returns {Function}
12604	 */
12605	var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;
12606
12607	/**
12608	 * Check if the given variable is a function
12609	 * @method
12610	 * @memberof Popper.Utils
12611	 * @argument {Any} functionToCheck - variable to check
12612	 * @returns {Boolean} answer to: is a function?
12613	 */
12614	function isFunction(functionToCheck) {
12615		var getType = {};
12616		return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
12617	}
12618
12619	/**
12620	 * Get CSS computed property of the given element
12621	 * @method
12622	 * @memberof Popper.Utils
12623	 * @argument {Eement} element
12624	 * @argument {String} property
12625	 */
12626	function getStyleComputedProperty(element, property) {
12627		if (element.nodeType !== 1) {
12628			return [];
12629		}
12630		// NOTE: 1 DOM access here
12631		var window = element.ownerDocument.defaultView;
12632		var css = window.getComputedStyle(element, null);
12633		return property ? css[property] : css;
12634	}
12635
12636	/**
12637	 * Returns the parentNode or the host of the element
12638	 * @method
12639	 * @memberof Popper.Utils
12640	 * @argument {Element} element
12641	 * @returns {Element} parent
12642	 */
12643	function getParentNode(element) {
12644		if (element.nodeName === 'HTML') {
12645			return element;
12646		}
12647		return element.parentNode || element.host;
12648	}
12649
12650	/**
12651	 * Returns the scrolling parent of the given element
12652	 * @method
12653	 * @memberof Popper.Utils
12654	 * @argument {Element} element
12655	 * @returns {Element} scroll parent
12656	 */
12657	function getScrollParent(element) {
12658		// Return body, `getScroll` will take care to get the correct `scrollTop` from it
12659		if (!element) {
12660			return document.body;
12661		}
12662
12663		switch (element.nodeName) {
12664			case 'HTML':
12665			case 'BODY':
12666				return element.ownerDocument.body;
12667			case '#document':
12668				return element.body;
12669		}
12670
12671		// Firefox want us to check `-x` and `-y` variations as well
12672
12673		var _getStyleComputedProp = getStyleComputedProperty(element),
12674			overflow = _getStyleComputedProp.overflow,
12675			overflowX = _getStyleComputedProp.overflowX,
12676			overflowY = _getStyleComputedProp.overflowY;
12677
12678		if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
12679			return element;
12680		}
12681
12682		return getScrollParent(getParentNode(element));
12683	}
12684
12685	/**
12686	 * Returns the reference node of the reference object, or the reference object itself.
12687	 * @method
12688	 * @memberof Popper.Utils
vendor: 8,725 bytes, lines 12689-12978
12689	 * @param {Element|Object} reference - the reference element (the popper will be relative to this)
12690	 * @returns {Element} parent
12691	 */
12692	function getReferenceNode(reference) {
12693		return reference && reference.referenceNode ? reference.referenceNode : reference;
12694	}
12695
12696	var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);
12697	var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
12698
12699	/**
12700	 * Determines if the browser is Internet Explorer
12701	 * @method
12702	 * @memberof Popper.Utils
12703	 * @param {Number} version to check
12704	 * @returns {Boolean} isIE
12705	 */
12706	function isIE(version) {
12707		if (version === 11) {
12708			return isIE11;
12709		}
12710		if (version === 10) {
12711			return isIE10;
12712		}
12713		return isIE11 || isIE10;
12714	}
12715
12716	/**
12717	 * Returns the offset parent of the given element
12718	 * @method
12719	 * @memberof Popper.Utils
12720	 * @argument {Element} element
12721	 * @returns {Element} offset parent
12722	 */
12723	function getOffsetParent(element) {
12724		if (!element) {
12725			return document.documentElement;
12726		}
12727
12728		var noOffsetParent = isIE(10) ? document.body : null;
12729
12730		// NOTE: 1 DOM access here
12731		var offsetParent = element.offsetParent || null;
12732		// Skip hidden elements which don't have an offsetParent
12733		while (offsetParent === noOffsetParent && element.nextElementSibling) {
12734			offsetParent = (element = element.nextElementSibling).offsetParent;
12735		}
12736
12737		var nodeName = offsetParent && offsetParent.nodeName;
12738
12739		if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
12740			return element ? element.ownerDocument.documentElement : document.documentElement;
12741		}
12742
12743		// .offsetParent will return the closest TH, TD or TABLE in case
12744		// no offsetParent is present, I hate this job...
12745		if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
12746			return getOffsetParent(offsetParent);
12747		}
12748
12749		return offsetParent;
12750	}
12751
12752	function isOffsetContainer(element) {
12753		var nodeName = element.nodeName;
12754
12755		if (nodeName === 'BODY') {
12756			return false;
12757		}
12758		return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
12759	}
12760
12761	/**
12762	 * Finds the root node (document, shadowDOM root) of the given element
12763	 * @method
12764	 * @memberof Popper.Utils
12765	 * @argument {Element} node
12766	 * @returns {Element} root node
12767	 */
12768	function getRoot(node) {
12769		if (node.parentNode !== null) {
12770			return getRoot(node.parentNode);
12771		}
12772
12773		return node;
12774	}
12775
12776	/**
12777	 * Finds the offset parent common to the two provided nodes
12778	 * @method
12779	 * @memberof Popper.Utils
12780	 * @argument {Element} element1
12781	 * @argument {Element} element2
12782	 * @returns {Element} common offset parent
12783	 */
12784	function findCommonOffsetParent(element1, element2) {
12785		// This check is needed to avoid errors in case one of the elements isn't defined for any reason
12786		if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
12787			return document.documentElement;
12788		}
12789
12790		// Here we make sure to give as "start" the element that comes first in the DOM
12791		var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
12792		var start = order ? element1 : element2;
12793		var end = order ? element2 : element1;
12794
12795		// Get common ancestor container
12796		var range = document.createRange();
12797		range.setStart(start, 0);
12798		range.setEnd(end, 0);
12799		var commonAncestorContainer = range.commonAncestorContainer;
12800
12801		// Both nodes are inside #document
12802
12803		if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
12804			if (isOffsetContainer(commonAncestorContainer)) {
12805				return commonAncestorContainer;
12806			}
12807
12808			return getOffsetParent(commonAncestorContainer);
12809		}
12810
12811		// one of the nodes is inside shadowDOM, find which one
12812		var element1root = getRoot(element1);
12813		if (element1root.host) {
12814			return findCommonOffsetParent(element1root.host, element2);
12815		} else {
12816			return findCommonOffsetParent(element1, getRoot(element2).host);
12817		}
12818	}
12819
12820	/**
12821	 * Gets the scroll value of the given element in the given side (top and left)
12822	 * @method
12823	 * @memberof Popper.Utils
12824	 * @argument {Element} element
12825	 * @argument {String} side `top` or `left`
12826	 * @returns {number} amount of scrolled pixels
12827	 */
12828	function getScroll(element) {
12829		var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
12830
12831		var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
12832		var nodeName = element.nodeName;
12833
12834		if (nodeName === 'BODY' || nodeName === 'HTML') {
12835			var html = element.ownerDocument.documentElement;
12836			var scrollingElement = element.ownerDocument.scrollingElement || html;
12837			return scrollingElement[upperSide];
12838		}
12839
12840		return element[upperSide];
12841	}
12842
12843	/*
12844   * Sum or subtract the element scroll values (left and top) from a given rect object
12845   * @method
12846   * @memberof Popper.Utils
12847   * @param {Object} rect - Rect object you want to change
12848   * @param {HTMLElement} element - The element from the function reads the scroll values
12849   * @param {Boolean} subtract - set to true if you want to subtract the scroll values
12850   * @return {Object} rect - The modifier rect object
12851   */
12852	function includeScroll(rect, element) {
12853		var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
12854
12855		var scrollTop = getScroll(element, 'top');
12856		var scrollLeft = getScroll(element, 'left');
12857		var modifier = subtract ? -1 : 1;
12858		rect.top += scrollTop * modifier;
12859		rect.bottom += scrollTop * modifier;
12860		rect.left += scrollLeft * modifier;
12861		rect.right += scrollLeft * modifier;
12862		return rect;
12863	}
12864
12865	/*
12866   * Helper to detect borders of a given element
12867   * @method
12868   * @memberof Popper.Utils
12869   * @param {CSSStyleDeclaration} styles
12870   * Result of `getStyleComputedProperty` on the given element
12871   * @param {String} axis - `x` or `y`
12872   * @return {number} borders - The borders size of the given axis
12873   */
12874
12875	function getBordersSize(styles, axis) {
12876		var sideA = axis === 'x' ? 'Left' : 'Top';
12877		var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
12878
12879		return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);
12880	}
12881
12882	function getSize(axis, body, html, computedStyle) {
12883		return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);
12884	}
12885
12886	function getWindowSizes(document) {
12887		var body = document.body;
12888		var html = document.documentElement;
12889		var computedStyle = isIE(10) && getComputedStyle(html);
12890
12891		return {
12892			height: getSize('Height', body, html, computedStyle),
12893			width: getSize('Width', body, html, computedStyle)
12894		};
12895	}
12896
12897	var classCallCheck = function (instance, Constructor) {
12898		if (!(instance instanceof Constructor)) {
12899			throw new TypeError("Cannot call a class as a function");
12900		}
12901	};
12902
12903	var createClass = function () {
12904		function defineProperties(target, props) {
12905			for (var i = 0; i < props.length; i++) {
12906				var descriptor = props[i];
12907				descriptor.enumerable = descriptor.enumerable || false;
12908				descriptor.configurable = true;
12909				if ("value" in descriptor) descriptor.writable = true;
12910				Object.defineProperty(target, descriptor.key, descriptor);
12911			}
12912		}
12913
12914		return function (Constructor, protoProps, staticProps) {
12915			if (protoProps) defineProperties(Constructor.prototype, protoProps);
12916			if (staticProps) defineProperties(Constructor, staticProps);
12917			return Constructor;
12918		};
12919	}();
12920
12921
12922
12923
12924
12925	var defineProperty = function (obj, key, value) {
12926		if (key in obj) {
12927			Object.defineProperty(obj, key, {
12928				value: value,
12929				enumerable: true,
12930				configurable: true,
12931				writable: true
12932			});
12933		} else {
12934			obj[key] = value;
12935		}
12936
12937		return obj;
12938	};
12939
12940	var _extends$1 = Object.assign || function (target) {
12941		for (var i = 1; i < arguments.length; i++) {
12942			var source = arguments[i];
12943
12944			for (var key in source) {
12945				if (Object.prototype.hasOwnProperty.call(source, key)) {
12946					target[key] = source[key];
12947				}
12948			}
12949		}
12950
12951		return target;
12952	};
12953
12954	/**
12955	 * Given element offsets, generate an output similar to getBoundingClientRect
12956	 * @method
12957	 * @memberof Popper.Utils
12958	 * @argument {Object} offsets
12959	 * @returns {Object} ClientRect like output
12960	 */
12961	function getClientRect(offsets) {
12962		return _extends$1({}, offsets, {
12963			right: offsets.left + offsets.width,
12964			bottom: offsets.top + offsets.height
12965		});
12966	}
12967
12968	/**
12969	 * Get bounding client rect of given element
12970	 * @method
12971	 * @memberof Popper.Utils
12972	 * @param {HTMLElement} element
12973	 * @return {Object} client rect
12974	 */
12975	function getBoundingClientRect(element) {
12976		var rect = {};
12977
12978		// IE10 10 FIX: Please, don't ask, the element isn't
vendor: 14,543 bytes, lines 12979-13416
12979		// considered in DOM in some circumstances...
12980		// This isn't reproducible in IE10 compatibility mode of IE11
12981		try {
12982			if (isIE(10)) {
12983				rect = element.getBoundingClientRect();
12984				var scrollTop = getScroll(element, 'top');
12985				var scrollLeft = getScroll(element, 'left');
12986				rect.top += scrollTop;
12987				rect.left += scrollLeft;
12988				rect.bottom += scrollTop;
12989				rect.right += scrollLeft;
12990			} else {
12991				rect = element.getBoundingClientRect();
12992			}
12993		} catch (e) {}
12994
12995		var result = {
12996			left: rect.left,
12997			top: rect.top,
12998			width: rect.right - rect.left,
12999			height: rect.bottom - rect.top
13000		};
13001
13002		// subtract scrollbar size from sizes
13003		var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
13004		var width = sizes.width || element.clientWidth || result.width;
13005		var height = sizes.height || element.clientHeight || result.height;
13006
13007		var horizScrollbar = element.offsetWidth - width;
13008		var vertScrollbar = element.offsetHeight - height;
13009
13010		// if an hypothetical scrollbar is detected, we must be sure it's not a `border`
13011		// we make this check conditional for performance reasons
13012		if (horizScrollbar || vertScrollbar) {
13013			var styles = getStyleComputedProperty(element);
13014			horizScrollbar -= getBordersSize(styles, 'x');
13015			vertScrollbar -= getBordersSize(styles, 'y');
13016
13017			result.width -= horizScrollbar;
13018			result.height -= vertScrollbar;
13019		}
13020
13021		return getClientRect(result);
13022	}
13023
13024	function getOffsetRectRelativeToArbitraryNode(children, parent) {
13025		var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
13026
13027		var isIE10 = isIE(10);
13028		var isHTML = parent.nodeName === 'HTML';
13029		var childrenRect = getBoundingClientRect(children);
13030		var parentRect = getBoundingClientRect(parent);
13031		var scrollParent = getScrollParent(children);
13032
13033		var styles = getStyleComputedProperty(parent);
13034		var borderTopWidth = parseFloat(styles.borderTopWidth);
13035		var borderLeftWidth = parseFloat(styles.borderLeftWidth);
13036
13037		// In cases where the parent is fixed, we must ignore negative scroll in offset calc
13038		if (fixedPosition && isHTML) {
13039			parentRect.top = Math.max(parentRect.top, 0);
13040			parentRect.left = Math.max(parentRect.left, 0);
13041		}
13042		var offsets = getClientRect({
13043			top: childrenRect.top - parentRect.top - borderTopWidth,
13044			left: childrenRect.left - parentRect.left - borderLeftWidth,
13045			width: childrenRect.width,
13046			height: childrenRect.height
13047		});
13048		offsets.marginTop = 0;
13049		offsets.marginLeft = 0;
13050
13051		// Subtract margins of documentElement in case it's being used as parent
13052		// we do this only on HTML because it's the only element that behaves
13053		// differently when margins are applied to it. The margins are included in
13054		// the box of the documentElement, in the other cases not.
13055		if (!isIE10 && isHTML) {
13056			var marginTop = parseFloat(styles.marginTop);
13057			var marginLeft = parseFloat(styles.marginLeft);
13058
13059			offsets.top -= borderTopWidth - marginTop;
13060			offsets.bottom -= borderTopWidth - marginTop;
13061			offsets.left -= borderLeftWidth - marginLeft;
13062			offsets.right -= borderLeftWidth - marginLeft;
13063
13064			// Attach marginTop and marginLeft because in some circumstances we may need them
13065			offsets.marginTop = marginTop;
13066			offsets.marginLeft = marginLeft;
13067		}
13068
13069		if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
13070			offsets = includeScroll(offsets, parent);
13071		}
13072
13073		return offsets;
13074	}
13075
13076	function getViewportOffsetRectRelativeToArtbitraryNode(element) {
13077		var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
13078
13079		var html = element.ownerDocument.documentElement;
13080		var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
13081		var width = Math.max(html.clientWidth, window.innerWidth || 0);
13082		var height = Math.max(html.clientHeight, window.innerHeight || 0);
13083
13084		var scrollTop = !excludeScroll ? getScroll(html) : 0;
13085		var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
13086
13087		var offset = {
13088			top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
13089			left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
13090			width: width,
13091			height: height
13092		};
13093
13094		return getClientRect(offset);
13095	}
13096
13097	/**
13098	 * Check if the given element is fixed or is inside a fixed parent
13099	 * @method
13100	 * @memberof Popper.Utils
13101	 * @argument {Element} element
13102	 * @argument {Element} customContainer
13103	 * @returns {Boolean} answer to "isFixed?"
13104	 */
13105	function isFixed(element) {
13106		var nodeName = element.nodeName;
13107		if (nodeName === 'BODY' || nodeName === 'HTML') {
13108			return false;
13109		}
13110		if (getStyleComputedProperty(element, 'position') === 'fixed') {
13111			return true;
13112		}
13113		var parentNode = getParentNode(element);
13114		if (!parentNode) {
13115			return false;
13116		}
13117		return isFixed(parentNode);
13118	}
13119
13120	/**
13121	 * Finds the first parent of an element that has a transformed property defined
13122	 * @method
13123	 * @memberof Popper.Utils
13124	 * @argument {Element} element
13125	 * @returns {Element} first transformed parent or documentElement
13126	 */
13127
13128	function getFixedPositionOffsetParent(element) {
13129		// This check is needed to avoid errors in case one of the elements isn't defined for any reason
13130		if (!element || !element.parentElement || isIE()) {
13131			return document.documentElement;
13132		}
13133		var el = element.parentElement;
13134		while (el && getStyleComputedProperty(el, 'transform') === 'none') {
13135			el = el.parentElement;
13136		}
13137		return el || document.documentElement;
13138	}
13139
13140	/**
13141	 * Computed the boundaries limits and return them
13142	 * @method
13143	 * @memberof Popper.Utils
13144	 * @param {HTMLElement} popper
13145	 * @param {HTMLElement} reference
13146	 * @param {number} padding
13147	 * @param {HTMLElement} boundariesElement - Element used to define the boundaries
13148	 * @param {Boolean} fixedPosition - Is in fixed position mode
13149	 * @returns {Object} Coordinates of the boundaries
13150	 */
13151	function getBoundaries(popper, reference, padding, boundariesElement) {
13152		var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
13153
13154		// NOTE: 1 DOM access here
13155
13156		var boundaries = { top: 0, left: 0 };
13157		var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
13158
13159		// Handle viewport case
13160		if (boundariesElement === 'viewport') {
13161			boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
13162		} else {
13163			// Handle other cases based on DOM element used as boundaries
13164			var boundariesNode = void 0;
13165			if (boundariesElement === 'scrollParent') {
13166				boundariesNode = getScrollParent(getParentNode(reference));
13167				if (boundariesNode.nodeName === 'BODY') {
13168					boundariesNode = popper.ownerDocument.documentElement;
13169				}
13170			} else if (boundariesElement === 'window') {
13171				boundariesNode = popper.ownerDocument.documentElement;
13172			} else {
13173				boundariesNode = boundariesElement;
13174			}
13175
13176			var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
13177
13178			// In case of HTML, we need a different computation
13179			if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
13180				var _getWindowSizes = getWindowSizes(popper.ownerDocument),
13181					height = _getWindowSizes.height,
13182					width = _getWindowSizes.width;
13183
13184				boundaries.top += offsets.top - offsets.marginTop;
13185				boundaries.bottom = height + offsets.top;
13186				boundaries.left += offsets.left - offsets.marginLeft;
13187				boundaries.right = width + offsets.left;
13188			} else {
13189				// for all the other DOM elements, this one is good
13190				boundaries = offsets;
13191			}
13192		}
13193
13194		// Add paddings
13195		padding = padding || 0;
13196		var isPaddingNumber = typeof padding === 'number';
13197		boundaries.left += isPaddingNumber ? padding : padding.left || 0;
13198		boundaries.top += isPaddingNumber ? padding : padding.top || 0;
13199		boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
13200		boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;
13201
13202		return boundaries;
13203	}
13204
13205	function getArea(_ref) {
13206		var width = _ref.width,
13207			height = _ref.height;
13208
13209		return width * height;
13210	}
13211
13212	/**
13213	 * Utility used to transform the `auto` placement to the placement with more
13214	 * available space.
13215	 * @method
13216	 * @memberof Popper.Utils
13217	 * @argument {Object} data - The data object generated by update method
13218	 * @argument {Object} options - Modifiers configuration and options
13219	 * @returns {Object} The data object, properly modified
13220	 */
13221	function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
13222		var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
13223
13224		if (placement.indexOf('auto') === -1) {
13225			return placement;
13226		}
13227
13228		var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
13229
13230		var rects = {
13231			top: {
13232				width: boundaries.width,
13233				height: refRect.top - boundaries.top
13234			},
13235			right: {
13236				width: boundaries.right - refRect.right,
13237				height: boundaries.height
13238			},
13239			bottom: {
13240				width: boundaries.width,
13241				height: boundaries.bottom - refRect.bottom
13242			},
13243			left: {
13244				width: refRect.left - boundaries.left,
13245				height: boundaries.height
13246			}
13247		};
13248
13249		var sortedAreas = Object.keys(rects).map(function (key) {
13250			return _extends$1({
13251				key: key
13252			}, rects[key], {
13253				area: getArea(rects[key])
13254			});
13255		}).sort(function (a, b) {
13256			return b.area - a.area;
13257		});
13258
13259		var filteredAreas = sortedAreas.filter(function (_ref2) {
13260			var width = _ref2.width,
13261				height = _ref2.height;
13262			return width >= popper.clientWidth && height >= popper.clientHeight;
13263		});
13264
13265		var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
13266
13267		var variation = placement.split('-')[1];
13268
13269		return computedPlacement + (variation ? '-' + variation : '');
13270	}
13271
13272	/**
13273	 * Get offsets to the reference element
13274	 * @method
13275	 * @memberof Popper.Utils
13276	 * @param {Object} state
13277	 * @param {Element} popper - the popper element
13278	 * @param {Element} reference - the reference element (the popper will be relative to this)
13279	 * @param {Element} fixedPosition - is in fixed position mode
13280	 * @returns {Object} An object containing the offsets which will be applied to the popper
13281	 */
13282	function getReferenceOffsets(state, popper, reference) {
13283		var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
13284
13285		var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
13286		return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);
13287	}
13288
13289	/**
13290	 * Get the outer sizes of the given element (offset size + margins)
13291	 * @method
13292	 * @memberof Popper.Utils
13293	 * @argument {Element} element
13294	 * @returns {Object} object containing width and height properties
13295	 */
13296	function getOuterSizes(element) {
13297		var window = element.ownerDocument.defaultView;
13298		var styles = window.getComputedStyle(element);
13299		var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
13300		var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
13301		var result = {
13302			width: element.offsetWidth + y,
13303			height: element.offsetHeight + x
13304		};
13305		return result;
13306	}
13307
13308	/**
13309	 * Get the opposite placement of the given one
13310	 * @method
13311	 * @memberof Popper.Utils
13312	 * @argument {String} placement
13313	 * @returns {String} flipped placement
13314	 */
13315	function getOppositePlacement(placement) {
13316		var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
13317		return placement.replace(/left|right|bottom|top/g, function (matched) {
13318			return hash[matched];
13319		});
13320	}
13321
13322	/**
13323	 * Get offsets to the popper
13324	 * @method
13325	 * @memberof Popper.Utils
13326	 * @param {Object} position - CSS position the Popper will get applied
13327	 * @param {HTMLElement} popper - the popper element
13328	 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
13329	 * @param {String} placement - one of the valid placement options
13330	 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
13331	 */
13332	function getPopperOffsets(popper, referenceOffsets, placement) {
13333		placement = placement.split('-')[0];
13334
13335		// Get popper node sizes
13336		var popperRect = getOuterSizes(popper);
13337
13338		// Add position, width and height to our offsets object
13339		var popperOffsets = {
13340			width: popperRect.width,
13341			height: popperRect.height
13342		};
13343
13344		// depending by the popper placement we have to compute its offsets slightly differently
13345		var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
13346		var mainSide = isHoriz ? 'top' : 'left';
13347		var secondarySide = isHoriz ? 'left' : 'top';
13348		var measurement = isHoriz ? 'height' : 'width';
13349		var secondaryMeasurement = !isHoriz ? 'height' : 'width';
13350
13351		popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
13352		if (placement === secondarySide) {
13353			popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
13354		} else {
13355			popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
13356		}
13357
13358		return popperOffsets;
13359	}
13360
13361	/**
13362	 * Mimics the `find` method of Array
13363	 * @method
13364	 * @memberof Popper.Utils
13365	 * @argument {Array} arr
13366	 * @argument prop
13367	 * @argument value
13368	 * @returns index or -1
13369	 */
13370	function find(arr, check) {
13371		// use native find if supported
13372		if (Array.prototype.find) {
13373			return arr.find(check);
13374		}
13375
13376		// use `filter` to obtain the same behavior of `find`
13377		return arr.filter(check)[0];
13378	}
13379
13380	/**
13381	 * Return the index of the matching object
13382	 * @method
13383	 * @memberof Popper.Utils
13384	 * @argument {Array} arr
13385	 * @argument prop
13386	 * @argument value
13387	 * @returns index or -1
13388	 */
13389	function findIndex(arr, prop, value) {
13390		// use native findIndex if supported
13391		if (Array.prototype.findIndex) {
13392			return arr.findIndex(function (cur) {
13393				return cur[prop] === value;
13394			});
13395		}
13396
13397		// use `find` + `indexOf` if `findIndex` isn't supported
13398		var match = find(arr, function (obj) {
13399			return obj[prop] === value;
13400		});
13401		return arr.indexOf(match);
13402	}
13403
13404	/**
13405	 * Loop trough the list of modifiers and run them in order,
13406	 * each of them will then edit the data object.
13407	 * @method
13408	 * @memberof Popper.Utils
13409	 * @param {dataObject} data
13410	 * @param {Array} modifiers
13411	 * @param {String} ends - Optional modifier name used as stopper
13412	 * @returns {dataObject}
13413	 */
13414	function runModifiers(modifiers, data, ends) {
13415		var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
13416
vendor: 41,452 bytes, lines 13417-14607
13417		modifiersToRun.forEach(function (modifier) {
13418			if (modifier['function']) {
13419				// eslint-disable-line dot-notation
13420				console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
13421			}
13422			var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation
13423			if (modifier.enabled && isFunction(fn)) {
13424				// Add properties to offsets to make them a complete clientRect object
13425				// we do this before each modifier to make sure the previous one doesn't
13426				// mess with these values
13427				data.offsets.popper = getClientRect(data.offsets.popper);
13428				data.offsets.reference = getClientRect(data.offsets.reference);
13429
13430				data = fn(data, modifier);
13431			}
13432		});
13433
13434		return data;
13435	}
13436
13437	/**
13438	 * Updates the position of the popper, computing the new offsets and applying
13439	 * the new style.<br />
13440	 * Prefer `scheduleUpdate` over `update` because of performance reasons.
13441	 * @method
13442	 * @memberof Popper
13443	 */
13444	function update() {
13445		// if popper is destroyed, don't perform any further update
13446		if (this.state.isDestroyed) {
13447			return;
13448		}
13449
13450		var data = {
13451			instance: this,
13452			styles: {},
13453			arrowStyles: {},
13454			attributes: {},
13455			flipped: false,
13456			offsets: {}
13457		};
13458
13459		// compute reference element offsets
13460		data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);
13461
13462		// compute auto placement, store placement inside the data object,
13463		// modifiers will be able to edit `placement` if needed
13464		// and refer to originalPlacement to know the original value
13465		data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
13466
13467		// store the computed placement inside `originalPlacement`
13468		data.originalPlacement = data.placement;
13469
13470		data.positionFixed = this.options.positionFixed;
13471
13472		// compute the popper offsets
13473		data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
13474
13475		data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';
13476
13477		// run the modifiers
13478		data = runModifiers(this.modifiers, data);
13479
13480		// the first `update` will call `onCreate` callback
13481		// the other ones will call `onUpdate` callback
13482		if (!this.state.isCreated) {
13483			this.state.isCreated = true;
13484			this.options.onCreate(data);
13485		} else {
13486			this.options.onUpdate(data);
13487		}
13488	}
13489
13490	/**
13491	 * Helper used to know if the given modifier is enabled.
13492	 * @method
13493	 * @memberof Popper.Utils
13494	 * @returns {Boolean}
13495	 */
13496	function isModifierEnabled(modifiers, modifierName) {
13497		return modifiers.some(function (_ref) {
13498			var name = _ref.name,
13499				enabled = _ref.enabled;
13500			return enabled && name === modifierName;
13501		});
13502	}
13503
13504	/**
13505	 * Get the prefixed supported property name
13506	 * @method
13507	 * @memberof Popper.Utils
13508	 * @argument {String} property (camelCase)
13509	 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
13510	 */
13511	function getSupportedPropertyName(property) {
13512		var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
13513		var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
13514
13515		for (var i = 0; i < prefixes.length; i++) {
13516			var prefix = prefixes[i];
13517			var toCheck = prefix ? '' + prefix + upperProp : property;
13518			if (typeof document.body.style[toCheck] !== 'undefined') {
13519				return toCheck;
13520			}
13521		}
13522		return null;
13523	}
13524
13525	/**
13526	 * Destroys the popper.
13527	 * @method
13528	 * @memberof Popper
13529	 */
13530	function destroy() {
13531		this.state.isDestroyed = true;
13532
13533		// touch DOM only if `applyStyle` modifier is enabled
13534		if (isModifierEnabled(this.modifiers, 'applyStyle')) {
13535			this.popper.removeAttribute('x-placement');
13536			this.popper.style.position = '';
13537			this.popper.style.top = '';
13538			this.popper.style.left = '';
13539			this.popper.style.right = '';
13540			this.popper.style.bottom = '';
13541			this.popper.style.willChange = '';
13542			this.popper.style[getSupportedPropertyName('transform')] = '';
13543		}
13544
13545		this.disableEventListeners();
13546
13547		// remove the popper if user explicitly asked for the deletion on destroy
13548		// do not use `remove` because IE11 doesn't support it
13549		if (this.options.removeOnDestroy) {
13550			this.popper.parentNode.removeChild(this.popper);
13551		}
13552		return this;
13553	}
13554
13555	/**
13556	 * Get the window associated with the element
13557	 * @argument {Element} element
13558	 * @returns {Window}
13559	 */
13560	function getWindow(element) {
13561		var ownerDocument = element.ownerDocument;
13562		return ownerDocument ? ownerDocument.defaultView : window;
13563	}
13564
13565	function attachToScrollParents(scrollParent, event, callback, scrollParents) {
13566		var isBody = scrollParent.nodeName === 'BODY';
13567		var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;
13568		target.addEventListener(event, callback, { passive: true });
13569
13570		if (!isBody) {
13571			attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
13572		}
13573		scrollParents.push(target);
13574	}
13575
13576	/**
13577	 * Setup needed event listeners used to update the popper position
13578	 * @method
13579	 * @memberof Popper.Utils
13580	 * @private
13581	 */
13582	function setupEventListeners(reference, options, state, updateBound) {
13583		// Resize event listener on window
13584		state.updateBound = updateBound;
13585		getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });
13586
13587		// Scroll event listener on scroll parents
13588		var scrollElement = getScrollParent(reference);
13589		attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
13590		state.scrollElement = scrollElement;
13591		state.eventsEnabled = true;
13592
13593		return state;
13594	}
13595
13596	/**
13597	 * It will add resize/scroll events and start recalculating
13598	 * position of the popper element when they are triggered.
13599	 * @method
13600	 * @memberof Popper
13601	 */
13602	function enableEventListeners() {
13603		if (!this.state.eventsEnabled) {
13604			this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
13605		}
13606	}
13607
13608	/**
13609	 * Remove event listeners used to update the popper position
13610	 * @method
13611	 * @memberof Popper.Utils
13612	 * @private
13613	 */
13614	function removeEventListeners(reference, state) {
13615		// Remove resize event listener on window
13616		getWindow(reference).removeEventListener('resize', state.updateBound);
13617
13618		// Remove scroll event listener on scroll parents
13619		state.scrollParents.forEach(function (target) {
13620			target.removeEventListener('scroll', state.updateBound);
13621		});
13622
13623		// Reset state
13624		state.updateBound = null;
13625		state.scrollParents = [];
13626		state.scrollElement = null;
13627		state.eventsEnabled = false;
13628		return state;
13629	}
13630
13631	/**
13632	 * It will remove resize/scroll events and won't recalculate popper position
13633	 * when they are triggered. It also won't trigger `onUpdate` callback anymore,
13634	 * unless you call `update` method manually.
13635	 * @method
13636	 * @memberof Popper
13637	 */
13638	function disableEventListeners() {
13639		if (this.state.eventsEnabled) {
13640			cancelAnimationFrame(this.scheduleUpdate);
13641			this.state = removeEventListeners(this.reference, this.state);
13642		}
13643	}
13644
13645	/**
13646	 * Tells if a given input is a number
13647	 * @method
13648	 * @memberof Popper.Utils
13649	 * @param {*} input to check
13650	 * @return {Boolean}
13651	 */
13652	function isNumeric(n) {
13653		return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
13654	}
13655
13656	/**
13657	 * Set the style to the given popper
13658	 * @method
13659	 * @memberof Popper.Utils
13660	 * @argument {Element} element - Element to apply the style to
13661	 * @argument {Object} styles
13662	 * Object with a list of properties and values which will be applied to the element
13663	 */
13664	function setStyles(element, styles) {
13665		Object.keys(styles).forEach(function (prop) {
13666			var unit = '';
13667			// add unit if the value is numeric and is one of the following
13668			if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
13669				unit = 'px';
13670			}
13671			element.style[prop] = styles[prop] + unit;
13672		});
13673	}
13674
13675	/**
13676	 * Set the attributes to the given popper
13677	 * @method
13678	 * @memberof Popper.Utils
13679	 * @argument {Element} element - Element to apply the attributes to
13680	 * @argument {Object} styles
13681	 * Object with a list of properties and values which will be applied to the element
13682	 */
13683	function setAttributes(element, attributes) {
13684		Object.keys(attributes).forEach(function (prop) {
13685			var value = attributes[prop];
13686			if (value !== false) {
13687				element.setAttribute(prop, attributes[prop]);
13688			} else {
13689				element.removeAttribute(prop);
13690			}
13691		});
13692	}
13693
13694	/**
13695	 * @function
13696	 * @memberof Modifiers
13697	 * @argument {Object} data - The data object generated by `update` method
13698	 * @argument {Object} data.styles - List of style properties - values to apply to popper element
13699	 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
13700	 * @argument {Object} options - Modifiers configuration and options
13701	 * @returns {Object} The same data object
13702	 */
13703	function applyStyle(data) {
13704		// any property present in `data.styles` will be applied to the popper,
13705		// in this way we can make the 3rd party modifiers add custom styles to it
13706		// Be aware, modifiers could override the properties defined in the previous
13707		// lines of this modifier!
13708		setStyles(data.instance.popper, data.styles);
13709
13710		// any property present in `data.attributes` will be applied to the popper,
13711		// they will be set as HTML attributes of the element
13712		setAttributes(data.instance.popper, data.attributes);
13713
13714		// if arrowElement is defined and arrowStyles has some properties
13715		if (data.arrowElement && Object.keys(data.arrowStyles).length) {
13716			setStyles(data.arrowElement, data.arrowStyles);
13717		}
13718
13719		return data;
13720	}
13721
13722	/**
13723	 * Set the x-placement attribute before everything else because it could be used
13724	 * to add margins to the popper margins needs to be calculated to get the
13725	 * correct popper offsets.
13726	 * @method
13727	 * @memberof Popper.modifiers
13728	 * @param {HTMLElement} reference - The reference element used to position the popper
13729	 * @param {HTMLElement} popper - The HTML element used as popper
13730	 * @param {Object} options - Popper.js options
13731	 */
13732	function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
13733		// compute reference element offsets
13734		var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
13735
13736		// compute auto placement, store placement inside the data object,
13737		// modifiers will be able to edit `placement` if needed
13738		// and refer to originalPlacement to know the original value
13739		var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
13740
13741		popper.setAttribute('x-placement', placement);
13742
13743		// Apply `position` to popper before anything else because
13744		// without the position applied we can't guarantee correct computations
13745		setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
13746
13747		return options;
13748	}
13749
13750	/**
13751	 * @function
13752	 * @memberof Popper.Utils
13753	 * @argument {Object} data - The data object generated by `update` method
13754	 * @argument {Boolean} shouldRound - If the offsets should be rounded at all
13755	 * @returns {Object} The popper's position offsets rounded
13756	 *
13757	 * The tale of pixel-perfect positioning. It's still not 100% perfect, but as
13758	 * good as it can be within reason.
13759	 * Discussion here: https://github.com/FezVrasta/popper.js/pull/715
13760	 *
13761	 * Low DPI screens cause a popper to be blurry if not using full pixels (Safari
13762	 * as well on High DPI screens).
13763	 *
13764	 * Firefox prefers no rounding for positioning and does not have blurriness on
13765	 * high DPI screens.
13766	 *
13767	 * Only horizontal placement and left/right values need to be considered.
13768	 */
13769	function getRoundedOffsets(data, shouldRound) {
13770		var _data$offsets = data.offsets,
13771			popper = _data$offsets.popper,
13772			reference = _data$offsets.reference;
13773		var round = Math.round,
13774			floor = Math.floor;
13775
13776		var noRound = function noRound(v) {
13777			return v;
13778		};
13779
13780		var referenceWidth = round(reference.width);
13781		var popperWidth = round(popper.width);
13782
13783		var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
13784		var isVariation = data.placement.indexOf('-') !== -1;
13785		var sameWidthParity = referenceWidth % 2 === popperWidth % 2;
13786		var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;
13787
13788		var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;
13789		var verticalToInteger = !shouldRound ? noRound : round;
13790
13791		return {
13792			left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),
13793			top: verticalToInteger(popper.top),
13794			bottom: verticalToInteger(popper.bottom),
13795			right: horizontalToInteger(popper.right)
13796		};
13797	}
13798
13799	var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
13800
13801	/**
13802	 * @function
13803	 * @memberof Modifiers
13804	 * @argument {Object} data - The data object generated by `update` method
13805	 * @argument {Object} options - Modifiers configuration and options
13806	 * @returns {Object} The data object, properly modified
13807	 */
13808	function computeStyle(data, options) {
13809		var x = options.x,
13810			y = options.y;
13811		var popper = data.offsets.popper;
13812
13813		// Remove this legacy support in Popper.js v2
13814
13815		var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
13816			return modifier.name === 'applyStyle';
13817		}).gpuAcceleration;
13818		if (legacyGpuAccelerationOption !== undefined) {
13819			console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
13820		}
13821		var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
13822
13823		var offsetParent = getOffsetParent(data.instance.popper);
13824		var offsetParentRect = getBoundingClientRect(offsetParent);
13825
13826		// Styles
13827		var styles = {
13828			position: popper.position
13829		};
13830
13831		var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);
13832
13833		var sideA = x === 'bottom' ? 'top' : 'bottom';
13834		var sideB = y === 'right' ? 'left' : 'right';
13835
13836		// if gpuAcceleration is set to `true` and transform is supported,
13837		//  we use `translate3d` to apply the position to the popper we
13838		// automatically use the supported prefixed version if needed
13839		var prefixedProperty = getSupportedPropertyName('transform');
13840
13841		// now, let's make a step back and look at this code closely (wtf?)
13842		// If the content of the popper grows once it's been positioned, it
13843		// may happen that the popper gets misplaced because of the new content
13844		// overflowing its reference element
13845		// To avoid this problem, we provide two options (x and y), which allow
13846		// the consumer to define the offset origin.
13847		// If we position a popper on top of a reference element, we can set
13848		// `x` to `top` to make the popper grow towards its top instead of
13849		// its bottom.
13850		var left = void 0,
13851			top = void 0;
13852		if (sideA === 'bottom') {
13853			// when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
13854			// and not the bottom of the html element
13855			if (offsetParent.nodeName === 'HTML') {
13856				top = -offsetParent.clientHeight + offsets.bottom;
13857			} else {
13858				top = -offsetParentRect.height + offsets.bottom;
13859			}
13860		} else {
13861			top = offsets.top;
13862		}
13863		if (sideB === 'right') {
13864			if (offsetParent.nodeName === 'HTML') {
13865				left = -offsetParent.clientWidth + offsets.right;
13866			} else {
13867				left = -offsetParentRect.width + offsets.right;
13868			}
13869		} else {
13870			left = offsets.left;
13871		}
13872		if (gpuAcceleration && prefixedProperty) {
13873			styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
13874			styles[sideA] = 0;
13875			styles[sideB] = 0;
13876			styles.willChange = 'transform';
13877		} else {
13878			// othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
13879			var invertTop = sideA === 'bottom' ? -1 : 1;
13880			var invertLeft = sideB === 'right' ? -1 : 1;
13881			styles[sideA] = top * invertTop;
13882			styles[sideB] = left * invertLeft;
13883			styles.willChange = sideA + ', ' + sideB;
13884		}
13885
13886		// Attributes
13887		var attributes = {
13888			'x-placement': data.placement
13889		};
13890
13891		// Update `data` attributes, styles and arrowStyles
13892		data.attributes = _extends$1({}, attributes, data.attributes);
13893		data.styles = _extends$1({}, styles, data.styles);
13894		data.arrowStyles = _extends$1({}, data.offsets.arrow, data.arrowStyles);
13895
13896		return data;
13897	}
13898
13899	/**
13900	 * Helper used to know if the given modifier depends from another one.<br />
13901	 * It checks if the needed modifier is listed and enabled.
13902	 * @method
13903	 * @memberof Popper.Utils
13904	 * @param {Array} modifiers - list of modifiers
13905	 * @param {String} requestingName - name of requesting modifier
13906	 * @param {String} requestedName - name of requested modifier
13907	 * @returns {Boolean}
13908	 */
13909	function isModifierRequired(modifiers, requestingName, requestedName) {
13910		var requesting = find(modifiers, function (_ref) {
13911			var name = _ref.name;
13912			return name === requestingName;
13913		});
13914
13915		var isRequired = !!requesting && modifiers.some(function (modifier) {
13916			return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
13917		});
13918
13919		if (!isRequired) {
13920			var _requesting = '`' + requestingName + '`';
13921			var requested = '`' + requestedName + '`';
13922			console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
13923		}
13924		return isRequired;
13925	}
13926
13927	/**
13928	 * @function
13929	 * @memberof Modifiers
13930	 * @argument {Object} data - The data object generated by update method
13931	 * @argument {Object} options - Modifiers configuration and options
13932	 * @returns {Object} The data object, properly modified
13933	 */
13934	function arrow(data, options) {
13935		var _data$offsets$arrow;
13936
13937		// arrow depends on keepTogether in order to work
13938		if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
13939			return data;
13940		}
13941
13942		var arrowElement = options.element;
13943
13944		// if arrowElement is a string, suppose it's a CSS selector
13945		if (typeof arrowElement === 'string') {
13946			arrowElement = data.instance.popper.querySelector(arrowElement);
13947
13948			// if arrowElement is not found, don't run the modifier
13949			if (!arrowElement) {
13950				return data;
13951			}
13952		} else {
13953			// if the arrowElement isn't a query selector we must check that the
13954			// provided DOM node is child of its popper node
13955			if (!data.instance.popper.contains(arrowElement)) {
13956				console.warn('WARNING: `arrow.element` must be child of its popper element!');
13957				return data;
13958			}
13959		}
13960
13961		var placement = data.placement.split('-')[0];
13962		var _data$offsets = data.offsets,
13963			popper = _data$offsets.popper,
13964			reference = _data$offsets.reference;
13965
13966		var isVertical = ['left', 'right'].indexOf(placement) !== -1;
13967
13968		var len = isVertical ? 'height' : 'width';
13969		var sideCapitalized = isVertical ? 'Top' : 'Left';
13970		var side = sideCapitalized.toLowerCase();
13971		var altSide = isVertical ? 'left' : 'top';
13972		var opSide = isVertical ? 'bottom' : 'right';
13973		var arrowElementSize = getOuterSizes(arrowElement)[len];
13974
13975		//
13976		// extends keepTogether behavior making sure the popper and its
13977		// reference have enough pixels in conjunction
13978		//
13979
13980		// top/left side
13981		if (reference[opSide] - arrowElementSize < popper[side]) {
13982			data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
13983		}
13984		// bottom/right side
13985		if (reference[side] + arrowElementSize > popper[opSide]) {
13986			data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
13987		}
13988		data.offsets.popper = getClientRect(data.offsets.popper);
13989
13990		// compute center of the popper
13991		var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
13992
13993		// Compute the sideValue using the updated popper offsets
13994		// take popper margin in account because we don't have this info available
13995		var css = getStyleComputedProperty(data.instance.popper);
13996		var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);
13997		var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);
13998		var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
13999
14000		// prevent arrowElement from being placed not contiguously to its popper
14001		sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
14002
14003		data.arrowElement = arrowElement;
14004		data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);
14005
14006		return data;
14007	}
14008
14009	/**
14010	 * Get the opposite placement variation of the given one
14011	 * @method
14012	 * @memberof Popper.Utils
14013	 * @argument {String} placement variation
14014	 * @returns {String} flipped placement variation
14015	 */
14016	function getOppositeVariation(variation) {
14017		if (variation === 'end') {
14018			return 'start';
14019		} else if (variation === 'start') {
14020			return 'end';
14021		}
14022		return variation;
14023	}
14024
14025	/**
14026	 * List of accepted placements to use as values of the `placement` option.<br />
14027	 * Valid placements are:
14028	 * - `auto`
14029	 * - `top`
14030	 * - `right`
14031	 * - `bottom`
14032	 * - `left`
14033	 *
14034	 * Each placement can have a variation from this list:
14035	 * - `-start`
14036	 * - `-end`
14037	 *
14038	 * Variations are interpreted easily if you think of them as the left to right
14039	 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
14040	 * is right.<br />
14041	 * Vertically (`left` and `right`), `start` is top and `end` is bottom.
14042	 *
14043	 * Some valid examples are:
14044	 * - `top-end` (on top of reference, right aligned)
14045	 * - `right-start` (on right of reference, top aligned)
14046	 * - `bottom` (on bottom, centered)
14047	 * - `auto-end` (on the side with more space available, alignment depends by placement)
14048	 *
14049	 * @static
14050	 * @type {Array}
14051	 * @enum {String}
14052	 * @readonly
14053	 * @method placements
14054	 * @memberof Popper
14055	 */
14056	var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
14057
14058	// Get rid of `auto` `auto-start` and `auto-end`
14059	var validPlacements = placements.slice(3);
14060
14061	/**
14062	 * Given an initial placement, returns all the subsequent placements
14063	 * clockwise (or counter-clockwise).
14064	 *
14065	 * @method
14066	 * @memberof Popper.Utils
14067	 * @argument {String} placement - A valid placement (it accepts variations)
14068	 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
14069	 * @returns {Array} placements including their variations
14070	 */
14071	function clockwise(placement) {
14072		var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
14073
14074		var index = validPlacements.indexOf(placement);
14075		var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
14076		return counter ? arr.reverse() : arr;
14077	}
14078
14079	var BEHAVIORS = {
14080		FLIP: 'flip',
14081		CLOCKWISE: 'clockwise',
14082		COUNTERCLOCKWISE: 'counterclockwise'
14083	};
14084
14085	/**
14086	 * @function
14087	 * @memberof Modifiers
14088	 * @argument {Object} data - The data object generated by update method
14089	 * @argument {Object} options - Modifiers configuration and options
14090	 * @returns {Object} The data object, properly modified
14091	 */
14092	function flip(data, options) {
14093		// if `inner` modifier is enabled, we can't use the `flip` modifier
14094		if (isModifierEnabled(data.instance.modifiers, 'inner')) {
14095			return data;
14096		}
14097
14098		if (data.flipped && data.placement === data.originalPlacement) {
14099			// seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
14100			return data;
14101		}
14102
14103		var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
14104
14105		var placement = data.placement.split('-')[0];
14106		var placementOpposite = getOppositePlacement(placement);
14107		var variation = data.placement.split('-')[1] || '';
14108
14109		var flipOrder = [];
14110
14111		switch (options.behavior) {
14112			case BEHAVIORS.FLIP:
14113				flipOrder = [placement, placementOpposite];
14114				break;
14115			case BEHAVIORS.CLOCKWISE:
14116				flipOrder = clockwise(placement);
14117				break;
14118			case BEHAVIORS.COUNTERCLOCKWISE:
14119				flipOrder = clockwise(placement, true);
14120				break;
14121			default:
14122				flipOrder = options.behavior;
14123		}
14124
14125		flipOrder.forEach(function (step, index) {
14126			if (placement !== step || flipOrder.length === index + 1) {
14127				return data;
14128			}
14129
14130			placement = data.placement.split('-')[0];
14131			placementOpposite = getOppositePlacement(placement);
14132
14133			var popperOffsets = data.offsets.popper;
14134			var refOffsets = data.offsets.reference;
14135
14136			// using floor because the reference offsets may contain decimals we are not going to consider here
14137			var floor = Math.floor;
14138			var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
14139
14140			var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
14141			var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
14142			var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
14143			var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
14144
14145			var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
14146
14147			// flip the variation if required
14148			var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
14149
14150			// flips variation if reference element overflows boundaries
14151			var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
14152
14153			// flips variation if popper content overflows boundaries
14154			var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);
14155
14156			var flippedVariation = flippedVariationByRef || flippedVariationByContent;
14157
14158			if (overlapsRef || overflowsBoundaries || flippedVariation) {
14159				// this boolean to detect any flip loop
14160				data.flipped = true;
14161
14162				if (overlapsRef || overflowsBoundaries) {
14163					placement = flipOrder[index + 1];
14164				}
14165
14166				if (flippedVariation) {
14167					variation = getOppositeVariation(variation);
14168				}
14169
14170				data.placement = placement + (variation ? '-' + variation : '');
14171
14172				// this object contains `position`, we want to preserve it along with
14173				// any additional property we may add in the future
14174				data.offsets.popper = _extends$1({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
14175
14176				data = runModifiers(data.instance.modifiers, data, 'flip');
14177			}
14178		});
14179		return data;
14180	}
14181
14182	/**
14183	 * @function
14184	 * @memberof Modifiers
14185	 * @argument {Object} data - The data object generated by update method
14186	 * @argument {Object} options - Modifiers configuration and options
14187	 * @returns {Object} The data object, properly modified
14188	 */
14189	function keepTogether(data) {
14190		var _data$offsets = data.offsets,
14191			popper = _data$offsets.popper,
14192			reference = _data$offsets.reference;
14193
14194		var placement = data.placement.split('-')[0];
14195		var floor = Math.floor;
14196		var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
14197		var side = isVertical ? 'right' : 'bottom';
14198		var opSide = isVertical ? 'left' : 'top';
14199		var measurement = isVertical ? 'width' : 'height';
14200
14201		if (popper[side] < floor(reference[opSide])) {
14202			data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
14203		}
14204		if (popper[opSide] > floor(reference[side])) {
14205			data.offsets.popper[opSide] = floor(reference[side]);
14206		}
14207
14208		return data;
14209	}
14210
14211	/**
14212	 * Converts a string containing value + unit into a px value number
14213	 * @function
14214	 * @memberof {modifiers~offset}
14215	 * @private
14216	 * @argument {String} str - Value + unit string
14217	 * @argument {String} measurement - `height` or `width`
14218	 * @argument {Object} popperOffsets
14219	 * @argument {Object} referenceOffsets
14220	 * @returns {Number|String}
14221	 * Value in pixels, or original string if no values were extracted
14222	 */
14223	function toValue(str, measurement, popperOffsets, referenceOffsets) {
14224		// separate value from unit
14225		var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
14226		var value = +split[1];
14227		var unit = split[2];
14228
14229		// If it's not a number it's an operator, I guess
14230		if (!value) {
14231			return str;
14232		}
14233
14234		if (unit.indexOf('%') === 0) {
14235			var element = void 0;
14236			switch (unit) {
14237				case '%p':
14238					element = popperOffsets;
14239					break;
14240				case '%':
14241				case '%r':
14242				default:
14243					element = referenceOffsets;
14244			}
14245
14246			var rect = getClientRect(element);
14247			return rect[measurement] / 100 * value;
14248		} else if (unit === 'vh' || unit === 'vw') {
14249			// if is a vh or vw, we calculate the size based on the viewport
14250			var size = void 0;
14251			if (unit === 'vh') {
14252				size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
14253			} else {
14254				size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
14255			}
14256			return size / 100 * value;
14257		} else {
14258			// if is an explicit pixel unit, we get rid of the unit and keep the value
14259			// if is an implicit unit, it's px, and we return just the value
14260			return value;
14261		}
14262	}
14263
14264	/**
14265	 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
14266	 * @function
14267	 * @memberof {modifiers~offset}
14268	 * @private
14269	 * @argument {String} offset
14270	 * @argument {Object} popperOffsets
14271	 * @argument {Object} referenceOffsets
14272	 * @argument {String} basePlacement
14273	 * @returns {Array} a two cells array with x and y offsets in numbers
14274	 */
14275	function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
14276		var offsets = [0, 0];
14277
14278		// Use height if placement is left or right and index is 0 otherwise use width
14279		// in this way the first offset will use an axis and the second one
14280		// will use the other one
14281		var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
14282
14283		// Split the offset string to obtain a list of values and operands
14284		// The regex addresses values with the plus or minus sign in front (+10, -20, etc)
14285		var fragments = offset.split(/(\+|\-)/).map(function (frag) {
14286			return frag.trim();
14287		});
14288
14289		// Detect if the offset string contains a pair of values or a single one
14290		// they could be separated by comma or space
14291		var divider = fragments.indexOf(find(fragments, function (frag) {
14292			return frag.search(/,|\s/) !== -1;
14293		}));
14294
14295		if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
14296			console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
14297		}
14298
14299		// If divider is found, we divide the list of values and operands to divide
14300		// them by ofset X and Y.
14301		var splitRegex = /\s*,\s*|\s+/;
14302		var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
14303
14304		// Convert the values with units to absolute pixels to allow our computations
14305		ops = ops.map(function (op, index) {
14306			// Most of the units rely on the orientation of the popper
14307			var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
14308			var mergeWithPrevious = false;
14309			return op
14310				// This aggregates any `+` or `-` sign that aren't considered operators
14311				// e.g.: 10 + +5 => [10, +, +5]
14312				.reduce(function (a, b) {
14313					if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
14314						a[a.length - 1] = b;
14315						mergeWithPrevious = true;
14316						return a;
14317					} else if (mergeWithPrevious) {
14318						a[a.length - 1] += b;
14319						mergeWithPrevious = false;
14320						return a;
14321					} else {
14322						return a.concat(b);
14323					}
14324				}, [])
14325				// Here we convert the string values into number values (in px)
14326				.map(function (str) {
14327					return toValue(str, measurement, popperOffsets, referenceOffsets);
14328				});
14329		});
14330
14331		// Loop trough the offsets arrays and execute the operations
14332		ops.forEach(function (op, index) {
14333			op.forEach(function (frag, index2) {
14334				if (isNumeric(frag)) {
14335					offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
14336				}
14337			});
14338		});
14339		return offsets;
14340	}
14341
14342	/**
14343	 * @function
14344	 * @memberof Modifiers
14345	 * @argument {Object} data - The data object generated by update method
14346	 * @argument {Object} options - Modifiers configuration and options
14347	 * @argument {Number|String} options.offset=0
14348	 * The offset value as described in the modifier description
14349	 * @returns {Object} The data object, properly modified
14350	 */
14351	function offset(data, _ref) {
14352		var offset = _ref.offset;
14353		var placement = data.placement,
14354			_data$offsets = data.offsets,
14355			popper = _data$offsets.popper,
14356			reference = _data$offsets.reference;
14357
14358		var basePlacement = placement.split('-')[0];
14359
14360		var offsets = void 0;
14361		if (isNumeric(+offset)) {
14362			offsets = [+offset, 0];
14363		} else {
14364			offsets = parseOffset(offset, popper, reference, basePlacement);
14365		}
14366
14367		if (basePlacement === 'left') {
14368			popper.top += offsets[0];
14369			popper.left -= offsets[1];
14370		} else if (basePlacement === 'right') {
14371			popper.top += offsets[0];
14372			popper.left += offsets[1];
14373		} else if (basePlacement === 'top') {
14374			popper.left += offsets[0];
14375			popper.top -= offsets[1];
14376		} else if (basePlacement === 'bottom') {
14377			popper.left += offsets[0];
14378			popper.top += offsets[1];
14379		}
14380
14381		data.popper = popper;
14382		return data;
14383	}
14384
14385	/**
14386	 * @function
14387	 * @memberof Modifiers
14388	 * @argument {Object} data - The data object generated by `update` method
14389	 * @argument {Object} options - Modifiers configuration and options
14390	 * @returns {Object} The data object, properly modified
14391	 */
14392	function preventOverflow(data, options) {
14393		var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
14394
14395		// If offsetParent is the reference element, we really want to
14396		// go one step up and use the next offsetParent as reference to
14397		// avoid to make this modifier completely useless and look like broken
14398		if (data.instance.reference === boundariesElement) {
14399			boundariesElement = getOffsetParent(boundariesElement);
14400		}
14401
14402		// NOTE: DOM access here
14403		// resets the popper's position so that the document size can be calculated excluding
14404		// the size of the popper element itself
14405		var transformProp = getSupportedPropertyName('transform');
14406		var popperStyles = data.instance.popper.style; // assignment to help minification
14407		var top = popperStyles.top,
14408			left = popperStyles.left,
14409			transform = popperStyles[transformProp];
14410
14411		popperStyles.top = '';
14412		popperStyles.left = '';
14413		popperStyles[transformProp] = '';
14414
14415		var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);
14416
14417		// NOTE: DOM access here
14418		// restores the original style properties after the offsets have been computed
14419		popperStyles.top = top;
14420		popperStyles.left = left;
14421		popperStyles[transformProp] = transform;
14422
14423		options.boundaries = boundaries;
14424
14425		var order = options.priority;
14426		var popper = data.offsets.popper;
14427
14428		var check = {
14429			primary: function primary(placement) {
14430				var value = popper[placement];
14431				if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
14432					value = Math.max(popper[placement], boundaries[placement]);
14433				}
14434				return defineProperty({}, placement, value);
14435			},
14436			secondary: function secondary(placement) {
14437				var mainSide = placement === 'right' ? 'left' : 'top';
14438				var value = popper[mainSide];
14439				if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
14440					value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
14441				}
14442				return defineProperty({}, mainSide, value);
14443			}
14444		};
14445
14446		order.forEach(function (placement) {
14447			var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
14448			popper = _extends$1({}, popper, check[side](placement));
14449		});
14450
14451		data.offsets.popper = popper;
14452
14453		return data;
14454	}
14455
14456	/**
14457	 * @function
14458	 * @memberof Modifiers
14459	 * @argument {Object} data - The data object generated by `update` method
14460	 * @argument {Object} options - Modifiers configuration and options
14461	 * @returns {Object} The data object, properly modified
14462	 */
14463	function shift(data) {
14464		var placement = data.placement;
14465		var basePlacement = placement.split('-')[0];
14466		var shiftvariation = placement.split('-')[1];
14467
14468		// if shift shiftvariation is specified, run the modifier
14469		if (shiftvariation) {
14470			var _data$offsets = data.offsets,
14471				reference = _data$offsets.reference,
14472				popper = _data$offsets.popper;
14473
14474			var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
14475			var side = isVertical ? 'left' : 'top';
14476			var measurement = isVertical ? 'width' : 'height';
14477
14478			var shiftOffsets = {
14479				start: defineProperty({}, side, reference[side]),
14480				end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
14481			};
14482
14483			data.offsets.popper = _extends$1({}, popper, shiftOffsets[shiftvariation]);
14484		}
14485
14486		return data;
14487	}
14488
14489	/**
14490	 * @function
14491	 * @memberof Modifiers
14492	 * @argument {Object} data - The data object generated by update method
14493	 * @argument {Object} options - Modifiers configuration and options
14494	 * @returns {Object} The data object, properly modified
14495	 */
14496	function hide(data) {
14497		if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
14498			return data;
14499		}
14500
14501		var refRect = data.offsets.reference;
14502		var bound = find(data.instance.modifiers, function (modifier) {
14503			return modifier.name === 'preventOverflow';
14504		}).boundaries;
14505
14506		if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
14507			// Avoid unnecessary DOM access if visibility hasn't changed
14508			if (data.hide === true) {
14509				return data;
14510			}
14511
14512			data.hide = true;
14513			data.attributes['x-out-of-boundaries'] = '';
14514		} else {
14515			// Avoid unnecessary DOM access if visibility hasn't changed
14516			if (data.hide === false) {
14517				return data;
14518			}
14519
14520			data.hide = false;
14521			data.attributes['x-out-of-boundaries'] = false;
14522		}
14523
14524		return data;
14525	}
14526
14527	/**
14528	 * @function
14529	 * @memberof Modifiers
14530	 * @argument {Object} data - The data object generated by `update` method
14531	 * @argument {Object} options - Modifiers configuration and options
14532	 * @returns {Object} The data object, properly modified
14533	 */
14534	function inner(data) {
14535		var placement = data.placement;
14536		var basePlacement = placement.split('-')[0];
14537		var _data$offsets = data.offsets,
14538			popper = _data$offsets.popper,
14539			reference = _data$offsets.reference;
14540
14541		var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
14542
14543		var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
14544
14545		popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
14546
14547		data.placement = getOppositePlacement(placement);
14548		data.offsets.popper = getClientRect(popper);
14549
14550		return data;
14551	}
14552
14553	/**
14554	 * Modifier function, each modifier can have a function of this type assigned
14555	 * to its `fn` property.<br />
14556	 * These functions will be called on each update, this means that you must
14557	 * make sure they are performant enough to avoid performance bottlenecks.
14558	 *
14559	 * @function ModifierFn
14560	 * @argument {dataObject} data - The data object generated by `update` method
14561	 * @argument {Object} options - Modifiers configuration and options
14562	 * @returns {dataObject} The data object, properly modified
14563	 */
14564
14565	/**
14566	 * Modifiers are plugins used to alter the behavior of your poppers.<br />
14567	 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
14568	 * needed by the library.
14569	 *
14570	 * Usually you don't want to override the `order`, `fn` and `onLoad` props.
14571	 * All the other properties are configurations that could be tweaked.
14572	 * @namespace modifiers
14573	 */
14574	var modifiers = {
14575		/**
14576		 * Modifier used to shift the popper on the start or end of its reference
14577		 * element.<br />
14578		 * It will read the variation of the `placement` property.<br />
14579		 * It can be one either `-end` or `-start`.
14580		 * @memberof modifiers
14581		 * @inner
14582		 */
14583		shift: {
14584			/** @prop {number} order=100 - Index used to define the order of execution */
14585			order: 100,
14586			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14587			enabled: true,
14588			/** @prop {ModifierFn} */
14589			fn: shift
14590		},
14591
14592		/**
14593		 * The `offset` modifier can shift your popper on both its axis.
14594		 *
14595		 * It accepts the following units:
14596		 * - `px` or unit-less, interpreted as pixels
14597		 * - `%` or `%r`, percentage relative to the length of the reference element
14598		 * - `%p`, percentage relative to the length of the popper element
14599		 * - `vw`, CSS viewport width unit
14600		 * - `vh`, CSS viewport height unit
14601		 *
14602		 * For length is intended the main axis relative to the placement of the popper.<br />
14603		 * This means that if the placement is `top` or `bottom`, the length will be the
14604		 * `width`. In case of `left` or `right`, it will be the `height`.
14605		 *
14606		 * You can provide a single value (as `Number` or `String`), or a pair of values
14607		 * as `String` divided by a comma or one (or more) white space
14607s.<br />
14608		 * The latter is a deprecated method because it leads to confusion and will be
14609		 * removed in v2.<br />
14610		 * Additionally, it accepts additions and subtractions between different units.
14611		 * Note that multiplications and divisions aren't supported.
14612		 *
14613		 * Valid examples are:
14614		 * ```
14615		 * 10
14616		 * '10%'
14617		 * '10, 10'
14618		 * '10%, 10'
14619		 * '10 + 10%'
14620		 * '10 - 5vh + 3%'
14621		 * '-10px + 5vh, 5px - 6%'
14622		 * ```
14623		 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
14624		 * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
14625		 * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
14626		 *
14627		 * @memberof modifiers
14628		 * @inner
14629		 */
14630		offset: {
14631			/** @prop {number} order=200 - Index used to define the order of execution */
14632			order: 200,
14633			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14634			enabled: true,
14635			/** @prop {ModifierFn} */
14636			fn: offset,
14637			/** @prop {Number|String} offset=0
14638			 * The offset value as described in the modifier description
14639			 */
14640			offset: 0
14641		},
14642
14643		/**
14644		 * Modifier used to prevent the popper from being positioned outside the boundary.
14645		 *
14646		 * A scenario exists where the reference itself is not within the boundaries.<br />
14647		 * We can say it has "escaped the boundaries" — or just "escaped".<br />
14648		 * In this case we need to decide whether the popper should either:
14649		 *
14650		 * - detach from the reference and remain "trapped" in the boundaries, or
14651		 * - if it should ignore the boundary and "escape with its reference"
14652		 *
14653		 * When `escapeWithReference` is set to`true` and reference is completely
14654		 * outside its boundaries, the popper will overflow (or completely leave)
14655		 * the boundaries in order to remain attached to the edge of the reference.
14656		 *
14657		 * @memberof modifiers
14658		 * @inner
14659		 */
14660		preventOverflow: {
14661			/** @prop {number} order=300 - Index used to define the order of execution */
14662			order: 300,
14663			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14664			enabled: true,
14665			/** @prop {ModifierFn} */
14666			fn: preventOverflow,
14667			/**
14668			 * @prop {Array} [priority=['left','right','top','bottom']]
14669			 * Popper will try to prevent overflow following these priorities by default,
14670			 * then, it could overflow on the left and on top of the `boundariesElement`
14671			 */
14672			priority: ['left', 'right', 'top', 'bottom'],
14673			/**
14674			 * @prop {number} padding=5
14675			 * Amount of pixel used to define a minimum distance between the boundaries
14676			 * and the popper. This makes sure the popper always has a little padding
14677			 * between the edges of its container
14678			 */
14679			padding: 5,
14680			/**
14681			 * @prop {String|HTMLElement} boundariesElement='scrollParent'
14682			 * Boundaries used by the modifier. Can be `scrollParent`, `window`,
14683			 * `viewport` or any DOM element.
14684			 */
14685			boundariesElement: 'scrollParent'
14686		},
14687
14688		/**
14689		 * Modifier used to make sure the reference and its popper stay near each other
14690		 * without leaving any gap between the two. Especially useful when the arrow is
14691		 * enabled and you want to ensure that it points to its reference element.
14692		 * It cares only about the first axis. You can still have poppers with margin
14693		 * between the popper and its reference element.
14694		 * @memberof modifiers
14695		 * @inner
14696		 */
14697		keepTogether: {
14698			/** @prop {number} order=400 - Index used to define the order of execution */
14699			order: 400,
14700			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14701			enabled: true,
14702			/** @prop {ModifierFn} */
14703			fn: keepTogether
14704		},
14705
14706		/**
14707		 * This modifier is used to move the `arrowElement` of the popper to make
14708		 * sure it is positioned between the reference element and its popper element.
14709		 * It will read the outer size of the `arrowElement` node to detect how many
14710		 * pixels of conjunction are needed.
14711		 *
14712		 * It has no effect if no `arrowElement` is provided.
14713		 * @memberof modifiers
14714		 * @inner
14715		 */
14716		arrow: {
14717			/** @prop {number} order=500 - Index used to define the order of execution */
14718			order: 500,
14719			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14720			enabled: true,
14721			/** @prop {ModifierFn} */
14722			fn: arrow,
14723			/** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
14724			element: '[x-arrow]'
14725		},
14726
14727		/**
14728		 * Modifier used to flip the popper's placement when it starts to overlap its
14729		 * reference element.
14730		 *
14731		 * Requires the `preventOverflow` modifier before it in order to work.
14732		 *
14733		 * **NOTE:** this modifier will interrupt the current update cycle and will
14734		 * restart it if it detects the need to flip the placement.
14735		 * @memberof modifiers
14736		 * @inner
14737		 */
14738		flip: {
14739			/** @prop {number} order=600 - Index used to define the order of execution */
14740			order: 600,
14741			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14742			enabled: true,
14743			/** @prop {ModifierFn} */
14744			fn: flip,
14745			/**
14746			 * @prop {String|Array} behavior='flip'
14747			 * The behavior used to change the popper's placement. It can be one of
14748			 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
14749			 * placements (with optional variations)
14750			 */
14751			behavior: 'flip',
14752			/**
14753			 * @prop {number} padding=5
14754			 * The popper will flip if it hits the edges of the `boundariesElement`
14755			 */
14756			padding: 5,
14757			/**
14758			 * @prop {String|HTMLElement} boundariesElement='viewport'
14759			 * The element which will define the boundaries of the popper position.
14760			 * The popper will never be placed outside of the defined boundaries
14761			 * (except if `keepTogether` is enabled)
14762			 */
14763			boundariesElement: 'viewport',
14764			/**
14765			 * @prop {Boolean} flipVariations=false
14766			 * The popper will switch placement variation between `-start` and `-end` when
14767			 * the reference element overlaps its boundaries.
14768			 *
14769			 * The original placement should have a set variation.
14770			 */
14771			flipVariations: false,
14772			/**
14773			 * @prop {Boolean} flipVariationsByContent=false
14774			 * The popper will switch placement variation between `-start` and `-end` when
14775			 * the popper element overlaps its reference boundaries.
14776			 *
14777			 * The original placement should have a set variation.
14778			 */
14779			flipVariationsByContent: false
14780		},
14781
14782		/**
14783		 * Modifier used to make the popper flow toward the inner of the reference element.
14784		 * By default, when this modifier is disabled, the popper will be placed outside
14785		 * the reference element.
14786		 * @memberof modifiers
14787		 * @inner
14788		 */
14789		inner: {
14790			/** @prop {number} order=700 - Index used to define the order of execution */
14791			order: 700,
14792			/** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
14793			enabled: false,
14794			/** @prop {ModifierFn} */
14795			fn: inner
14796		},
14797
14798		/**
14799		 * Modifier used to hide the popper when its reference element is outside of the
14800		 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
14801		 * be used to hide with a CSS selector the popper when its reference is
14802		 * out of boundaries.
14803		 *
14804		 * Requires the `preventOverflow` modifier before it in order to work.
14805		 * @memberof modifiers
14806		 * @inner
14807		 */
14808		hide: {
14809			/** @prop {number} order=800 - Index used to define the order of execution */
14810			order: 800,
14811			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14812			enabled: true,
14813			/** @prop {ModifierFn} */
14814			fn: hide
14815		},
14816
14817		/**
14818		 * Computes the style that will be applied to the popper element to gets
14819		 * properly positioned.
14820		 *
14821		 * Note that this modifier will not touch the DOM, it just prepares the styles
14822		 * so that `applyStyle` modifier can apply it. This separation is useful
14823		 * in case you need to replace `applyStyle` with a custom implementation.
14824		 *
14825		 * This modifier has `850` as `order` value to maintain backward compatibility
14826		 * with previous versions of Popper.js. Expect the modifiers ordering method
14827		 * to change in future major versions of the library.
14828		 *
14829		 * @memberof modifiers
14830		 * @inner
14831		 */
14832		computeStyle: {
14833			/** @prop {number} order=850 - Index used to define the order of execution */
14834			order: 850,
14835			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14836			enabled: true,
14837			/** @prop {ModifierFn} */
14838			fn: computeStyle,
14839			/**
14840			 * @prop {Boolean} gpuAcceleration=true
14841			 * If true, it uses the CSS 3D transformation to position the popper.
14842			 * Otherwise, it will use the `top` and `left` properties
14843			 */
14844			gpuAcceleration: true,
14845			/**
14846			 * @prop {string} [x='bottom']
14847			 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
14848			 * Change this if your popper should grow in a direction different from `bottom`
14849			 */
14850			x: 'bottom',
14851			/**
14852			 * @prop {string} [x='left']
14853			 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
14854			 * Change this if your popper should grow in a direction different from `right`
14855			 */
14856			y: 'right'
14857		},
14858
14859		/**
14860		 * Applies the computed styles to the popper element.
14861		 *
14862		 * All the DOM manipulations are limited to this modifier. This is useful in case
14863		 * you want to integrate Popper.js inside a framework or view library and you
14864		 * want to delegate all the DOM manipulations to it.
14865		 *
14866		 * Note that if you disable this modifier, you must make sure the popper element
14867		 * has its position set to `absolute` before Popper.js can do its work!
14868		 *
14869		 * Just disable this modifier and define your own to achieve the desired effect.
14870		 *
14871		 * @memberof modifiers
14872		 * @inner
14873		 */
14874		applyStyle: {
14875			/** @prop {number} order=900 - Index used to define the order of execution */
14876			order: 900,
14877			/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14878			enabled: true,
14879			/** @prop {ModifierFn} */
14880			fn: applyStyle,
14881			/** @prop {Function} */
14882			onLoad: applyStyleOnLoad,
14883			/**
14884			 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
14885			 * @prop {Boolean} gpuAcceleration=true
14886			 * If true, it uses the CSS 3D transformation to position the popper.
14887			 * Otherwise, it will use the `top` and `left` properties
14888			 */
14889			gpuAcceleration: undefined
14890		}
14891	};
14892
14893	/**
14894	 * The `dataObject` is an object containing all the information used by Popper.js.
14895	 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
14896	 * @name dataObject
14897	 * @property {Object} data.instance The Popper.js instance
14898	 * @property {String} data.placement Placement applied to popper
14899	 * @property {String} data.originalPlacement Placement originally defined on init
14900	 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
14901	 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
14902	 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
14903	 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
14904	 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
14905	 * @property {Object} data.boundaries Offsets of the popper boundaries
14906	 * @property {Object} data.offsets The measurements of popper, reference and arrow elements
14907	 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
14908	 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
14909	 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
14910	 */
14911
14912	/**
14913	 * Default options provided to Popper.js constructor.<br />
14914	 * These can be overridden using the `options` argument of Popper.js.<br />
14915	 * To override an option, simply pass an object with the same
14916	 * structure of the `options` object, as the 3rd argument. For example:
14917	 * ```
14918	 * new Popper(ref, pop, {
14919	 *   modifiers: {
14920	 *     preventOverflow: { enabled: false }
14921	 *   }
14922	 * })
14923	 * ```
14924	 * @type {Object}
14925	 * @static
14926	 * @memberof Popper
14927	 */
14928	var Defaults = {
14929		/**
14930		 * Popper's placement.
14931		 * @prop {Popper.placements} placement='bottom'
14932		 */
14933		placement: 'bottom',
14934
14935		/**
14936		 * Set this to true if you want popper to position it self in 'fixed' mode
14937		 * @prop {Boolean} positionFixed=false
14938		 */
14939		positionFixed: false,
14940
14941		/**
14942		 * Whether events (resize, scroll) are initially enabled.
14943		 * @prop {Boolean} eventsEnabled=true
14944		 */
14945		eventsEnabled: true,
14946
14947		/**
14948		 * Set to true if you want to automatically remove the popper when
14949		 * you call the `destroy` method.
14950		 * @prop {Boolean} removeOnDestroy=false
14951		 */
14952		removeOnDestroy: false,
14953
14954		/**
14955		 * Callback called when the popper is created.<br />
14956		 * By default, it is set to no-op.<br />
14957		 * Access Popper.js instance with `data.instance`.
14958		 * @prop {onCreate}
14959		 */
14960		onCreate: function onCreate() {},
14961
14962		/**
14963		 * Callback called when the popper is updated. This callback is not called
14964		 * on the initialization/creation of the popper, but only on subsequent
14965		 * updates.<br />
14966		 * By default, it is set to no-op.<br />
14967		 * Access Popper.js instance with `data.instance`.
14968		 * @prop {onUpdate}
14969		 */
14970		onUpdate: function onUpdate() {},
14971
14972		/**
14973		 * List of modifiers used to modify the offsets before they are applied to the popper.
14974		 * They provide most of the functionalities of Popper.js.
14975		 * @prop {modifiers}
14976		 */
14977		modifiers: modifiers
14978	};
14979
14980	/**
14981	 * @callback onCreate
14982	 * @param {dataObject} data
14983	 */
14984
14985	/**
14986	 * @callback onUpdate
14987	 * @param {dataObject} data
14988	 */
14989
14990		// Utils
14991		// Methods
14992	var Popper = function () {
14993			/**
14994			 * Creates a new Popper.js instance.
14995			 * @class Popper
14996			 * @param {Element|referenceObject} reference - The reference element used to position the popper
14997			 * @param {Element} popper - The HTML / XML element used as the popper
14998			 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
14999			 * @return {Object} instance - The generated Popper.js instance
15000			 */
15001			function Popper(reference, popper) {
15002				var _this = this;
15003
15004				var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
15005				classCallCheck(this, Popper);
15006
15007				this.scheduleUpdate = function () {
15008					return requestAnimationFrame(_this.update);
15009				};
15010
15011				// make update() debounced, so that it only runs at most once-per-tick
15012				this.update = debounce(this.update.bind(this));
15013
15014				// with {} we create a new object with the options inside it
15015				this.options = _extends$1({}, Popper.Defaults, options);
15016
15017				// init state
15018				this.state = {
vendor: 13,772 bytes, lines 15019-15442
15019					isDestroyed: false,
15020					isCreated: false,
15021					scrollParents: []
15022				};
15023
15024				// get reference and popper elements (allow jQuery wrappers)
15025				this.reference = reference && reference.jquery ? reference[0] : reference;
15026				this.popper = popper && popper.jquery ? popper[0] : popper;
15027
15028				// Deep merge modifiers options
15029				this.options.modifiers = {};
15030				Object.keys(_extends$1({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
15031					_this.options.modifiers[name] = _extends$1({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
15032				});
15033
15034				// Refactoring modifiers' list (Object => Array)
15035				this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
15036					return _extends$1({
15037						name: name
15038					}, _this.options.modifiers[name]);
15039				})
15040					// sort the modifiers by order
15041					.sort(function (a, b) {
15042						return a.order - b.order;
15043					});
15044
15045				// modifiers have the ability to execute arbitrary code when Popper.js get inited
15046				// such code is executed in the same order of its modifier
15047				// they could add new properties to their options configuration
15048				// BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
15049				this.modifiers.forEach(function (modifierOptions) {
15050					if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
15051						modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
15052					}
15053				});
15054
15055				// fire the first update to position the popper in the right place
15056				this.update();
15057
15058				var eventsEnabled = this.options.eventsEnabled;
15059				if (eventsEnabled) {
15060					// setup event listeners, they will take care of update the position in specific situations
15061					this.enableEventListeners();
15062				}
15063
15064				this.state.eventsEnabled = eventsEnabled;
15065			}
15066
15067			// We can't use class properties because they don't get listed in the
15068			// class prototype and break stuff like Sinon stubs
15069
15070
15071			createClass(Popper, [{
15072				key: 'update',
15073				value: function update$$1() {
15074					return update.call(this);
15075				}
15076			}, {
15077				key: 'destroy',
15078				value: function destroy$$1() {
15079					return destroy.call(this);
15080				}
15081			}, {
15082				key: 'enableEventListeners',
15083				value: function enableEventListeners$$1() {
15084					return enableEventListeners.call(this);
15085				}
15086			}, {
15087				key: 'disableEventListeners',
15088				value: function disableEventListeners$$1() {
15089					return disableEventListeners.call(this);
15090				}
15091
15092				/**
15093				 * Schedules an update. It will run on the next UI update available.
15094				 * @method scheduleUpdate
15095				 * @memberof Popper
15096				 */
15097
15098
15099				/**
15100				 * Collection of utilities useful when writing custom modifiers.
15101				 * Starting from version 1.7, this method is available only if you
15102				 * include `popper-utils.js` before `popper.js`.
15103				 *
15104				 * **DEPRECATION**: This way to access PopperUtils is deprecated
15105				 * and will be removed in v2! Use the PopperUtils module directly instead.
15106				 * Due to the high instability of the methods contained in Utils, we can't
15107				 * guarantee them to follow semver. Use them at your own risk!
15108				 * @static
15109				 * @private
15110				 * @type {Object}
15111				 * @deprecated since version 1.8
15112				 * @member Utils
15113				 * @memberof Popper
15114				 */
15115
15116			}]);
15117			return Popper;
15118		}();
15119
15120	/**
15121	 * The `referenceObject` is an object that provides an interface compatible with Popper.js
15122	 * and lets you use it as replacement of a real DOM node.<br />
15123	 * You can use this method to position a popper relatively to a set of coordinates
15124	 * in case you don't have a DOM node to use as reference.
15125	 *
15126	 * ```
15127	 * new Popper(referenceObject, popperNode);
15128	 * ```
15129	 *
15130	 * NB: This feature isn't supported in Internet Explorer 10.
15131	 * @name referenceObject
15132	 * @property {Function} data.getBoundingClientRect
15133	 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
15134	 * @property {number} data.clientWidth
15135	 * An ES6 getter that will return the width of the virtual reference element.
15136	 * @property {number} data.clientHeight
15137	 * An ES6 getter that will return the height of the virtual reference element.
15138	 */
15139
15140
15141	Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
15142	Popper.placements = placements;
15143	Popper.Defaults = Defaults;
15144
15145	/**
15146	 * ------------------------------------------------------------------------
15147	 * Constants
15148	 * ------------------------------------------------------------------------
15149	 */
15150
15151	var NAME$4 = 'dropdown';
15152	var VERSION$4 = '4.5.3';
15153	var DATA_KEY$4 = 'bs.dropdown';
15154	var EVENT_KEY$4 = "." + DATA_KEY$4;
15155	var DATA_API_KEY$4 = '.data-api';
15156	var JQUERY_NO_CONFLICT$4 = $__default['default'].fn[NAME$4];
15157	var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
15158
15159	var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
15160
15161	var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
15162
15163	var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
15164
15165	var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
15166
15167	var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
15168
15169	var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
15170	var EVENT_HIDE$1 = "hide" + EVENT_KEY$4;
15171	var EVENT_HIDDEN$1 = "hidden" + EVENT_KEY$4;
15172	var EVENT_SHOW$1 = "show" + EVENT_KEY$4;
15173	var EVENT_SHOWN$1 = "shown" + EVENT_KEY$4;
15174	var EVENT_CLICK = "click" + EVENT_KEY$4;
15175	var EVENT_CLICK_DATA_API$4 = "click" + EVENT_KEY$4 + DATA_API_KEY$4;
15176	var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY$4 + DATA_API_KEY$4;
15177	var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY$4 + DATA_API_KEY$4;
15178	var CLASS_NAME_DISABLED = 'disabled';
15179	var CLASS_NAME_SHOW$2 = 'show';
15180	var CLASS_NAME_DROPUP = 'dropup';
15181	var CLASS_NAME_DROPRIGHT = 'dropright';
15182	var CLASS_NAME_DROPLEFT = 'dropleft';
15183	var CLASS_NAME_MENURIGHT = 'dropdown-menu-right';
15184	var CLASS_NAME_POSITION_STATIC = 'position-static';
15185	var SELECTOR_DATA_TOGGLE$2 = '[data-toggle="dropdown"]';
15186	var SELECTOR_FORM_CHILD = '.dropdown form';
15187	var SELECTOR_MENU = '.dropdown-menu';
15188	var SELECTOR_NAVBAR_NAV = '.navbar-nav';
15189	var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
15190	var PLACEMENT_TOP = 'top-start';
15191	var PLACEMENT_TOPEND = 'top-end';
15192	var PLACEMENT_BOTTOM = 'bottom-start';
15193	var PLACEMENT_BOTTOMEND = 'bottom-end';
15194	var PLACEMENT_RIGHT = 'right-start';
15195	var PLACEMENT_LEFT = 'left-start';
15196	var Default$2 = {
15197		offset: 0,
15198		flip: true,
15199		boundary: 'scrollParent',
15200		reference: 'toggle',
15201		display: 'dynamic',
15202		popperConfig: null
15203	};
15204	var DefaultType$2 = {
15205		offset: '(number|string|function)',
15206		flip: 'boolean',
15207		boundary: '(string|element)',
15208		reference: '(string|element)',
15209		display: 'string',
15210		popperConfig: '(null|object)'
15211	};
15212	/**
15213	 * ------------------------------------------------------------------------
15214	 * Class Definition
15215	 * ------------------------------------------------------------------------
15216	 */
15217
15218	var Dropdown = /*#__PURE__*/function () {
15219		function Dropdown(element, config) {
15220			this._element = element;
15221			this._popper = null;
15222			this._config = this._getConfig(config);
15223			this._menu = this._getMenuElement();
15224			this._inNavbar = this._detectNavbar();
15225
15226			this._addEventListeners();
15227		} // Getters
15228
15229
15230		var _proto = Dropdown.prototype;
15231
15232		// Public
15233		_proto.toggle = function toggle() {
15234			if (this._element.disabled || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED)) {
15235				return;
15236			}
15237
15238			var isActive = $__default['default'](this._menu).hasClass(CLASS_NAME_SHOW$2);
15239
15240			Dropdown._clearMenus();
15241
15242			if (isActive) {
15243				return;
15244			}
15245
15246			this.show(true);
15247		};
15248
15249		_proto.show = function show(usePopper) {
15250			if (usePopper === void 0) {
15251				usePopper = false;
15252			}
15253
15254			if (this._element.disabled || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED) || $__default['default'](this._menu).hasClass(CLASS_NAME_SHOW$2)) {
15255				return;
15256			}
15257
15258			var relatedTarget = {
15259				relatedTarget: this._element
15260			};
15261			var showEvent = $__default['default'].Event(EVENT_SHOW$1, relatedTarget);
15262
15263			var parent = Dropdown._getParentFromElement(this._element);
15264
15265			$__default['default'](parent).trigger(showEvent);
15266
15267			if (showEvent.isDefaultPrevented()) {
15268				return;
15269			} // Disable totally Popper.js for Dropdown in Navbar
15270
15271
15272			if (!this._inNavbar && usePopper) {
15273				/**
15274				 * Check for Popper dependency
15275				 * Popper - https://popper.js.org
15276				 */
15277				if (typeof Popper === 'undefined') {
15278					throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)');
15279				}
15280
15281				var referenceElement = this._element;
15282
15283				if (this._config.reference === 'parent') {
15284					referenceElement = parent;
15285				} else if (Util.isElement(this._config.reference)) {
15286					referenceElement = this._config.reference; // Check if it's jQuery element
15287
15288					if (typeof this._config.reference.jquery !== 'undefined') {
15289						referenceElement = this._config.reference[0];
15290					}
15291				} // If boundary is not `scrollParent`, then set position to `static`
15292				// to allow the menu to "escape" the scroll parent's boundaries
15293				// https://github.com/twbs/bootstrap/issues/24251
15294
15295
15296				if (this._config.boundary !== 'scrollParent') {
15297					$__default['default'](parent).addClass(CLASS_NAME_POSITION_STATIC);
15298				}
15299
15300				// this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
15301			} // If this is a touch-enabled device we add extra
15302			// empty mouseover listeners to the body's immediate children;
15303			// only needed because of broken event delegation on iOS
15304			// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
15305
15306
15307			if ('ontouchstart' in document.documentElement && $__default['default'](parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {
15308				$__default['default'](document.body).children().on('mouseover', null, $__default['default'].noop);
15309			}
15310
15311			this._element.focus();
15312
15313			this._element.setAttribute('aria-expanded', true);
15314
15315			$__default['default'](this._menu).toggleClass(CLASS_NAME_SHOW$2);
15316			$__default['default'](parent).toggleClass(CLASS_NAME_SHOW$2).trigger($__default['default'].Event(EVENT_SHOWN$1, relatedTarget));
15317		};
15318
15319		_proto.hide = function hide() {
15320			if (this._element.disabled || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED) || !$__default['default'](this._menu).hasClass(CLASS_NAME_SHOW$2)) {
15321				return;
15322			}
15323
15324			var relatedTarget = {
15325				relatedTarget: this._element
15326			};
15327			var hideEvent = $__default['default'].Event(EVENT_HIDE$1, relatedTarget);
15328
15329			var parent = Dropdown._getParentFromElement(this._element);
15330
15331			$__default['default'](parent).trigger(hideEvent);
15332
15333			if (hideEvent.isDefaultPrevented()) {
15334				return;
15335			}
15336
15337			if (this._popper) {
15338				this._popper.destroy();
15339			}
15340
15341			$__default['default'](this._menu).toggleClass(CLASS_NAME_SHOW$2);
15342			$__default['default'](parent).toggleClass(CLASS_NAME_SHOW$2).trigger($__default['default'].Event(EVENT_HIDDEN$1, relatedTarget));
15343		};
15344
15345		_proto.dispose = function dispose() {
15346			$__default['default'].removeData(this._element, DATA_KEY$4);
15347			$__default['default'](this._element).off(EVENT_KEY$4);
15348			this._element = null;
15349			this._menu = null;
15350
15351			if (this._popper !== null) {
15352				this._popper.destroy();
15353
15354				this._popper = null;
15355			}
15356		};
15357
15358		_proto.update = function update() {
15359			this._inNavbar = this._detectNavbar();
15360
15361			if (this._popper !== null) {
15362				this._popper.scheduleUpdate();
15363			}
15364		} // Private
15365		;
15366
15367		_proto._addEventListeners = function _addEventListeners() {
15368			var _this = this;
15369
15370			$__default['default'](this._element).on(EVENT_CLICK, function (event) {
15371				event.preventDefault();
15372				event.stopPropagation();
15373
15374				_this.toggle();
15375			});
15376		};
15377
15378		_proto._getConfig = function _getConfig(config) {
15379			config = _extends({}, this.constructor.Default, $__default['default'](this._element).data(), config);
15380			Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
15381			return config;
15382		};
15383
15384		_proto._getMenuElement = function _getMenuElement() {
15385			if (!this._menu) {
15386				var parent = Dropdown._getParentFromElement(this._element);
15387
15388				if (parent) {
15389					this._menu = parent.querySelector(SELECTOR_MENU);
15390				}
15391			}
15392
15393			return this._menu;
15394		};
15395
15396		_proto._getPlacement = function _getPlacement() {
15397			var $parentDropdown = $__default['default'](this._element.parentNode);
15398			var placement = PLACEMENT_BOTTOM; // Handle dropup
15399
15400			if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {
15401				placement = $__default['default'](this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP;
15402			} else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {
15403				placement = PLACEMENT_RIGHT;
15404			} else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {
15405				placement = PLACEMENT_LEFT;
15406			} else if ($__default['default'](this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
15407				placement = PLACEMENT_BOTTOMEND;
15408			}
15409
15410			return placement;
15411		};
15412
15413		_proto._detectNavbar = function _detectNavbar() {
15414			return $__default['default'](this._element).closest('.navbar').length > 0;
15415		};
15416
15417		_proto._getOffset = function _getOffset() {
15418			var _this2 = this;
15419
15420			var offset = {};
15421
15422			if (typeof this._config.offset === 'function') {
15423				offset.fn = function (data) {
15424					data.offsets = _extends({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {});
15425					return data;
15426				};
15427			} else {
15428				offset.offset = this._config.offset;
15429			}
15430
15431			return offset;
15432		};
15433
15434		_proto._getPopperConfig = function _getPopperConfig() {
15435			var popperConfig = {
15436				placement: this._getPlacement(),
15437				modifiers: {
15438					offset: this._getOffset(),
15439					flip: {
15440						enabled: this._config.flip
15441					},
15442					preventOverflow: {
vendor: 8,828 bytes, lines 15443-15722
15443						boundariesElement: this._config.boundary
15444					}
15445				}
15446			}; // Disable Popper.js if we have a static display
15447
15448			if (this._config.display === 'static') {
15449				popperConfig.modifiers.applyStyle = {
15450					enabled: false
15451				};
15452			}
15453
15454			return _extends({}, popperConfig, this._config.popperConfig);
15455		} // Static
15456		;
15457
15458		Dropdown._jQueryInterface = function _jQueryInterface(config) {
15459			return this.each(function () {
15460				var data = $__default['default'](this).data(DATA_KEY$4);
15461
15462				var _config = typeof config === 'object' ? config : null;
15463
15464				if (!data) {
15465					data = new Dropdown(this, _config);
15466					$__default['default'](this).data(DATA_KEY$4, data);
15467				}
15468
15469				if (typeof config === 'string') {
15470					if (typeof data[config] === 'undefined') {
15471						throw new TypeError("No method named \"" + config + "\"");
15472					}
15473
15474					data[config]();
15475				}
15476			});
15477		};
15478
15479		Dropdown._clearMenus = function _clearMenus(event) {
15480			if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
15481				return;
15482			}
15483
15484			var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$2));
15485
15486			for (var i = 0, len = toggles.length; i < len; i++) {
15487				var parent = Dropdown._getParentFromElement(toggles[i]);
15488
15489				var context = $__default['default'](toggles[i]).data(DATA_KEY$4);
15490				var relatedTarget = {
15491					relatedTarget: toggles[i]
15492				};
15493
15494				if (event && event.type === 'click') {
15495					relatedTarget.clickEvent = event;
15496				}
15497
15498				if (!context) {
15499					continue;
15500				}
15501
15502				var dropdownMenu = context._menu;
15503
15504				if (!$__default['default'](parent).hasClass(CLASS_NAME_SHOW$2)) {
15505					continue;
15506				}
15507
15508				if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $__default['default'].contains(parent, event.target)) {
15509					continue;
15510				}
15511
15512				var hideEvent = $__default['default'].Event(EVENT_HIDE$1, relatedTarget);
15513				$__default['default'](parent).trigger(hideEvent);
15514
15515				if (hideEvent.isDefaultPrevented()) {
15516					continue;
15517				} // If this is a touch-enabled device we remove the extra
15518				// empty mouseover listeners we added for iOS support
15519
15520
15521				if ('ontouchstart' in document.documentElement) {
15522					$__default['default'](document.body).children().off('mouseover', null, $__default['default'].noop);
15523				}
15524
15525				toggles[i].setAttribute('aria-expanded', 'false');
15526
15527				if (context._popper) {
15528					context._popper.destroy();
15529				}
15530
15531				$__default['default'](dropdownMenu).removeClass(CLASS_NAME_SHOW$2);
15532				$__default['default'](parent).removeClass(CLASS_NAME_SHOW$2).trigger($__default['default'].Event(EVENT_HIDDEN$1, relatedTarget));
15533			}
15534		};
15535
15536		Dropdown._getParentFromElement = function _getParentFromElement(element) {
15537			var parent;
15538			var selector = Util.getSelectorFromElement(element);
15539
15540			if (selector) {
15541				parent = document.querySelector(selector);
15542			}
15543
15544			return parent || element.parentNode;
15545		} // eslint-disable-next-line complexity
15546		;
15547
15548		Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
15549			// If not input/textarea:
15550			//  - And not a key in REGEXP_KEYDOWN => not a dropdown command
15551			// If input/textarea:
15552			//  - If space key => not a dropdown command
15553			//  - If key is other than escape
15554			//    - If key is not up or down => not a dropdown command
15555			//    - If trigger inside the menu => not a dropdown command
15556			if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $__default['default'](event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
15557				return;
15558			}
15559
15560			if (this.disabled || $__default['default'](this).hasClass(CLASS_NAME_DISABLED)) {
15561				return;
15562			}
15563
15564			var parent = Dropdown._getParentFromElement(this);
15565
15566			var isActive = $__default['default'](parent).hasClass(CLASS_NAME_SHOW$2);
15567
15568			if (!isActive && event.which === ESCAPE_KEYCODE) {
15569				return;
15570			}
15571
15572			event.preventDefault();
15573			event.stopPropagation();
15574
15575			if (!isActive || event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE) {
15576				if (event.which === ESCAPE_KEYCODE) {
15577					$__default['default'](parent.querySelector(SELECTOR_DATA_TOGGLE$2)).trigger('focus');
15578				}
15579
15580				$__default['default'](this).trigger('click');
15581				return;
15582			}
15583
15584			var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) {
15585				return $__default['default'](item).is(':visible');
15586			});
15587
15588			if (items.length === 0) {
15589				return;
15590			}
15591
15592			var index = items.indexOf(event.target);
15593
15594			if (event.which === ARROW_UP_KEYCODE && index > 0) {
15595				// Up
15596				index--;
15597			}
15598
15599			if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
15600				// Down
15601				index++;
15602			}
15603
15604			if (index < 0) {
15605				index = 0;
15606			}
15607
15608			items[index].focus();
15609		};
15610
15611		_createClass(Dropdown, null, [{
15612			key: "VERSION",
15613			get: function get() {
15614				return VERSION$4;
15615			}
15616		}, {
15617			key: "Default",
15618			get: function get() {
15619				return Default$2;
15620			}
15621		}, {
15622			key: "DefaultType",
15623			get: function get() {
15624				return DefaultType$2;
15625			}
15626		}]);
15627
15628		return Dropdown;
15629	}();
15630	/**
15631	 * ------------------------------------------------------------------------
15632	 * Data Api implementation
15633	 * ------------------------------------------------------------------------
15634	 */
15635
15636
15637	$__default['default'](document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$2, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API$4 + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$2, function (event) {
15638		event.preventDefault();
15639		event.stopPropagation();
15640
15641		Dropdown._jQueryInterface.call($__default['default'](this), 'toggle');
15642	}).on(EVENT_CLICK_DATA_API$4, SELECTOR_FORM_CHILD, function (e) {
15643		e.stopPropagation();
15644	});
15645	/**
15646	 * ------------------------------------------------------------------------
15647	 * jQuery
15648	 * ------------------------------------------------------------------------
15649	 */
15650
15651	$__default['default'].fn[NAME$4] = Dropdown._jQueryInterface;
15652	$__default['default'].fn[NAME$4].Constructor = Dropdown;
15653
15654	$__default['default'].fn[NAME$4].noConflict = function () {
15655		$__default['default'].fn[NAME$4] = JQUERY_NO_CONFLICT$4;
15656		return Dropdown._jQueryInterface;
15657	};
15658
15659	/**
15660	 * ------------------------------------------------------------------------
15661	 * Constants
15662	 * ------------------------------------------------------------------------
15663	 */
15664
15665	var NAME$5 = 'modal';
15666	var VERSION$5 = '4.5.3';
15667	var DATA_KEY$5 = 'bs.modal';
15668	var EVENT_KEY$5 = "." + DATA_KEY$5;
15669	var DATA_API_KEY$5 = '.data-api';
15670	var JQUERY_NO_CONFLICT$5 = $__default['default'].fn[NAME$5];
15671	var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key
15672
15673	var Default$3 = {
15674		backdrop: true,
15675		keyboard: true,
15676		focus: true,
15677		show: true
15678	};
15679	var DefaultType$3 = {
15680		backdrop: '(boolean|string)',
15681		keyboard: 'boolean',
15682		focus: 'boolean',
15683		show: 'boolean'
15684	};
15685	var EVENT_HIDE$2 = "hide" + EVENT_KEY$5;
15686	var EVENT_HIDE_PREVENTED = "hidePrevented" + EVENT_KEY$5;
15687	var EVENT_HIDDEN$2 = "hidden" + EVENT_KEY$5;
15688	var EVENT_SHOW$2 = "show" + EVENT_KEY$5;
15689	var EVENT_SHOWN$2 = "shown" + EVENT_KEY$5;
15690	var EVENT_FOCUSIN = "focusin" + EVENT_KEY$5;
15691	var EVENT_RESIZE = "resize" + EVENT_KEY$5;
15692	var EVENT_CLICK_DISMISS = "click.dismiss" + EVENT_KEY$5;
15693	var EVENT_KEYDOWN_DISMISS = "keydown.dismiss" + EVENT_KEY$5;
15694	var EVENT_MOUSEUP_DISMISS = "mouseup.dismiss" + EVENT_KEY$5;
15695	var EVENT_MOUSEDOWN_DISMISS = "mousedown.dismiss" + EVENT_KEY$5;
15696	var EVENT_CLICK_DATA_API$5 = "click" + EVENT_KEY$5 + DATA_API_KEY$5;
15697	var CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable';
15698	var CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
15699	var CLASS_NAME_BACKDROP = 'modal-backdrop';
15700	var CLASS_NAME_OPEN = 'modal-open';
15701	var CLASS_NAME_FADE$1 = 'fade';
15702	var CLASS_NAME_SHOW$3 = 'show';
15703	var CLASS_NAME_STATIC = 'modal-static';
15704	var SELECTOR_DIALOG = '.modal-dialog';
15705	var SELECTOR_MODAL_BODY = '.modal-body';
15706	var SELECTOR_DATA_TOGGLE$3 = '[data-toggle="modal"]';
15707	var SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]';
15708	var SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
15709	var SELECTOR_STICKY_CONTENT = '.sticky-top';
15710	/**
15711	 * ------------------------------------------------------------------------
15712	 * Class Definition
15713	 * ------------------------------------------------------------------------
15714	 */
15715
15716	var Modal = /*#__PURE__*/function () {
15717		function Modal(element, config) {
15718			this._config = this._getConfig(config);
15719			this._element = element;
15720			this._dialog = element.querySelector(SELECTOR_DIALOG);
15721			this._backdrop = null;
15722			this._isShown = false;
vendor: 15,330 bytes, lines 15723-16197
15723			this._isBodyOverflowing = false;
15724			this._ignoreBackdropClick = false;
15725			this._isTransitioning = false;
15726			this._scrollbarWidth = 0;
15727		} // Getters
15728
15729
15730		var _proto = Modal.prototype;
15731
15732		// Public
15733		_proto.toggle = function toggle(relatedTarget) {
15734			return this._isShown ? this.hide() : this.show(relatedTarget);
15735		};
15736
15737		_proto.show = function show(relatedTarget) {
15738			var _this = this;
15739
15740			if (this._isShown || this._isTransitioning) {
15741				return;
15742			}
15743
15744			if ($__default['default'](this._element).hasClass(CLASS_NAME_FADE$1)) {
15745				this._isTransitioning = true;
15746			}
15747
15748			var showEvent = $__default['default'].Event(EVENT_SHOW$2, {
15749				relatedTarget: relatedTarget
15750			});
15751			$__default['default'](this._element).trigger(showEvent);
15752
15753			if (this._isShown || showEvent.isDefaultPrevented()) {
15754				return;
15755			}
15756
15757			this._isShown = true;
15758
15759			this._checkScrollbar();
15760
15761			this._setScrollbar();
15762
15763			this._adjustDialog();
15764
15765			this._setEscapeEvent();
15766
15767			this._setResizeEvent();
15768
15769			$__default['default'](this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, function (event) {
15770				return _this.hide(event);
15771			});
15772			$__default['default'](this._dialog).on(EVENT_MOUSEDOWN_DISMISS, function () {
15773				$__default['default'](_this._element).one(EVENT_MOUSEUP_DISMISS, function (event) {
15774					if ($__default['default'](event.target).is(_this._element)) {
15775						_this._ignoreBackdropClick = true;
15776					}
15777				});
15778			});
15779
15780			this._showBackdrop(function () {
15781				return _this._showElement(relatedTarget);
15782			});
15783		};
15784
15785		_proto.hide = function hide(event) {
15786			var _this2 = this;
15787
15788			if (event) {
15789				event.preventDefault();
15790			}
15791
15792			if (!this._isShown || this._isTransitioning) {
15793				return;
15794			}
15795
15796			var hideEvent = $__default['default'].Event(EVENT_HIDE$2);
15797			$__default['default'](this._element).trigger(hideEvent);
15798
15799			if (!this._isShown || hideEvent.isDefaultPrevented()) {
15800				return;
15801			}
15802
15803			this._isShown = false;
15804			var transition = $__default['default'](this._element).hasClass(CLASS_NAME_FADE$1);
15805
15806			if (transition) {
15807				this._isTransitioning = true;
15808			}
15809
15810			this._setEscapeEvent();
15811
15812			this._setResizeEvent();
15813
15814			$__default['default'](document).off(EVENT_FOCUSIN);
15815			$__default['default'](this._element).removeClass(CLASS_NAME_SHOW$3);
15816			$__default['default'](this._element).off(EVENT_CLICK_DISMISS);
15817			$__default['default'](this._dialog).off(EVENT_MOUSEDOWN_DISMISS);
15818
15819			if (transition) {
15820				var transitionDuration = Util.getTransitionDurationFromElement(this._element);
15821				$__default['default'](this._element).one(Util.TRANSITION_END, function (event) {
15822					return _this2._hideModal(event);
15823				}).emulateTransitionEnd(transitionDuration);
15824			} else {
15825				this._hideModal();
15826			}
15827		};
15828
15829		_proto.dispose = function dispose() {
15830			[window, this._element, this._dialog].forEach(function (htmlElement) {
15831				return $__default['default'](htmlElement).off(EVENT_KEY$5);
15832			});
15833			/**
15834			 * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
15835			 * Do not move `document` in `htmlElements` array
15836			 * It will remove `EVENT_CLICK_DATA_API` event that should remain
15837			 */
15838
15839			$__default['default'](document).off(EVENT_FOCUSIN);
15840			$__default['default'].removeData(this._element, DATA_KEY$5);
15841			this._config = null;
15842			this._element = null;
15843			this._dialog = null;
15844			this._backdrop = null;
15845			this._isShown = null;
15846			this._isBodyOverflowing = null;
15847			this._ignoreBackdropClick = null;
15848			this._isTransitioning = null;
15849			this._scrollbarWidth = null;
15850		};
15851
15852		_proto.handleUpdate = function handleUpdate() {
15853			this._adjustDialog();
15854		} // Private
15855		;
15856
15857		_proto._getConfig = function _getConfig(config) {
15858			config = _extends({}, Default$3, config);
15859			Util.typeCheckConfig(NAME$5, config, DefaultType$3);
15860			return config;
15861		};
15862
15863		_proto._triggerBackdropTransition = function _triggerBackdropTransition() {
15864			var _this3 = this;
15865
15866			if (this._config.backdrop === 'static') {
15867				var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED);
15868				$__default['default'](this._element).trigger(hideEventPrevented);
15869
15870				if (hideEventPrevented.isDefaultPrevented()) {
15871					return;
15872				}
15873
15874				var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
15875
15876				if (!isModalOverflowing) {
15877					this._element.style.overflowY = 'hidden';
15878				}
15879
15880				this._element.classList.add(CLASS_NAME_STATIC);
15881
15882				var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog);
15883				$__default['default'](this._element).off(Util.TRANSITION_END);
15884				$__default['default'](this._element).one(Util.TRANSITION_END, function () {
15885					_this3._element.classList.remove(CLASS_NAME_STATIC);
15886
15887					if (!isModalOverflowing) {
15888						$__default['default'](_this3._element).one(Util.TRANSITION_END, function () {
15889							_this3._element.style.overflowY = '';
15890						}).emulateTransitionEnd(_this3._element, modalTransitionDuration);
15891					}
15892				}).emulateTransitionEnd(modalTransitionDuration);
15893
15894				this._element.focus();
15895			} else {
15896				this.hide();
15897			}
15898		};
15899
15900		_proto._showElement = function _showElement(relatedTarget) {
15901			var _this4 = this;
15902
15903			var transition = $__default['default'](this._element).hasClass(CLASS_NAME_FADE$1);
15904			var modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null;
15905
15906			if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
15907				// Don't move modal's DOM position
15908				document.body.appendChild(this._element);
15909			}
15910
15911			this._element.style.display = 'block';
15912
15913			this._element.removeAttribute('aria-hidden');
15914
15915			this._element.setAttribute('aria-modal', true);
15916
15917			this._element.setAttribute('role', 'dialog');
15918
15919			if ($__default['default'](this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
15920				modalBody.scrollTop = 0;
15921			} else {
15922				this._element.scrollTop = 0;
15923			}
15924
15925			if (transition) {
15926				Util.reflow(this._element);
15927			}
15928
15929			$__default['default'](this._element).addClass(CLASS_NAME_SHOW$3);
15930
15931			if (this._config.focus) {
15932				this._enforceFocus();
15933			}
15934
15935			var shownEvent = $__default['default'].Event(EVENT_SHOWN$2, {
15936				relatedTarget: relatedTarget
15937			});
15938
15939			var transitionComplete = function transitionComplete() {
15940				if (_this4._config.focus) {
15941					_this4._element.focus();
15942				}
15943
15944				_this4._isTransitioning = false;
15945				$__default['default'](_this4._element).trigger(shownEvent);
15946			};
15947
15948			if (transition) {
15949				var transitionDuration = Util.getTransitionDurationFromElement(this._dialog);
15950				$__default['default'](this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);
15951			} else {
15952				transitionComplete();
15953			}
15954		};
15955
15956		_proto._enforceFocus = function _enforceFocus() {
15957			var _this5 = this;
15958
15959			$__default['default'](document).off(EVENT_FOCUSIN) // Guard against infinite focus loop
15960				.on(EVENT_FOCUSIN, function (event) {
15961					if (document !== event.target && _this5._element !== event.target && $__default['default'](_this5._element).has(event.target).length === 0) {
15962						_this5._element.focus();
15963					}
15964				});
15965		};
15966
15967		_proto._setEscapeEvent = function _setEscapeEvent() {
15968			var _this6 = this;
15969
15970			if (this._isShown) {
15971				$__default['default'](this._element).on(EVENT_KEYDOWN_DISMISS, function (event) {
15972					if (_this6._config.keyboard && event.which === ESCAPE_KEYCODE$1) {
15973						event.preventDefault();
15974
15975						_this6.hide();
15976					} else if (!_this6._config.keyboard && event.which === ESCAPE_KEYCODE$1) {
15977						_this6._triggerBackdropTransition();
15978					}
15979				});
15980			} else if (!this._isShown) {
15981				$__default['default'](this._element).off(EVENT_KEYDOWN_DISMISS);
15982			}
15983		};
15984
15985		_proto._setResizeEvent = function _setResizeEvent() {
15986			var _this7 = this;
15987
15988			if (this._isShown) {
15989				$__default['default'](window).on(EVENT_RESIZE, function (event) {
15990					return _this7.handleUpdate(event);
15991				});
15992			} else {
15993				$__default['default'](window).off(EVENT_RESIZE);
15994			}
15995		};
15996
15997		_proto._hideModal = function _hideModal() {
15998			var _this8 = this;
15999
16000			this._element.style.display = 'none';
16001
16002			this._element.setAttribute('aria-hidden', true);
16003
16004			this._element.removeAttribute('aria-modal');
16005
16006			this._element.removeAttribute('role');
16007
16008			this._isTransitioning = false;
16009
16010			this._showBackdrop(function () {
16011				$__default['default'](document.body).removeClass(CLASS_NAME_OPEN);
16012
16013				_this8._resetAdjustments();
16014
16015				_this8._resetScrollbar();
16016
16017				$__default['default'](_this8._element).trigger(EVENT_HIDDEN$2);
16018			});
16019		};
16020
16021		_proto._removeBackdrop = function _removeBackdrop() {
16022			if (this._backdrop) {
16023				$__default['default'](this._backdrop).remove();
16024				this._backdrop = null;
16025			}
16026		};
16027
16028		_proto._showBackdrop = function _showBackdrop(callback) {
16029			var _this9 = this;
16030
16031			var animate = $__default['default'](this._element).hasClass(CLASS_NAME_FADE$1) ? CLASS_NAME_FADE$1 : '';
16032
16033			if (this._isShown && this._config.backdrop) {
16034				this._backdrop = document.createElement('div');
16035				this._backdrop.className = CLASS_NAME_BACKDROP;
16036
16037				if (animate) {
16038					this._backdrop.classList.add(animate);
16039				}
16040
16041				$__default['default'](this._backdrop).appendTo(document.body);
16042				$__default['default'](this._element).on(EVENT_CLICK_DISMISS, function (event) {
16043					if (_this9._ignoreBackdropClick) {
16044						_this9._ignoreBackdropClick = false;
16045						return;
16046					}
16047
16048					if (event.target !== event.currentTarget) {
16049						return;
16050					}
16051
16052					_this9._triggerBackdropTransition();
16053				});
16054
16055				if (animate) {
16056					Util.reflow(this._backdrop);
16057				}
16058
16059				$__default['default'](this._backdrop).addClass(CLASS_NAME_SHOW$3);
16060
16061				if (!callback) {
16062					return;
16063				}
16064
16065				if (!animate) {
16066					callback();
16067					return;
16068				}
16069
16070				var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
16071				$__default['default'](this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);
16072			} else if (!this._isShown && this._backdrop) {
16073				$__default['default'](this._backdrop).removeClass(CLASS_NAME_SHOW$3);
16074
16075				var callbackRemove = function callbackRemove() {
16076					_this9._removeBackdrop();
16077
16078					if (callback) {
16079						callback();
16080					}
16081				};
16082
16083				if ($__default['default'](this._element).hasClass(CLASS_NAME_FADE$1)) {
16084					var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
16085
16086					$__default['default'](this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);
16087				} else {
16088					callbackRemove();
16089				}
16090			} else if (callback) {
16091				callback();
16092			}
16093		} // ----------------------------------------------------------------------
16094		// the following methods are used to handle overflowing modals
16095		// todo (fat): these should probably be refactored out of modal.js
16096		// ----------------------------------------------------------------------
16097		;
16098
16099		_proto._adjustDialog = function _adjustDialog() {
16100			var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
16101
16102			if (!this._isBodyOverflowing && isModalOverflowing) {
16103				this._element.style.paddingLeft = this._scrollbarWidth + "px";
16104			}
16105
16106			if (this._isBodyOverflowing && !isModalOverflowing) {
16107				this._element.style.paddingRight = this._scrollbarWidth + "px";
16108			}
16109		};
16110
16111		_proto._resetAdjustments = function _resetAdjustments() {
16112			this._element.style.paddingLeft = '';
16113			this._element.style.paddingRight = '';
16114		};
16115
16116		_proto._checkScrollbar = function _checkScrollbar() {
16117			var rect = document.body.getBoundingClientRect();
16118			this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
16119			this._scrollbarWidth = this._getScrollbarWidth();
16120		};
16121
16122		_proto._setScrollbar = function _setScrollbar() {
16123			var _this10 = this;
16124
16125			if (this._isBodyOverflowing) {
16126				// Note: DOMNode.style.paddingRight returns the actual value or '' if not set
16127				//   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
16128				var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT));
16129				var stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT)); // Adjust fixed content padding
16130
16131				$__default['default'](fixedContent).each(function (index, element) {
16132					var actualPadding = element.style.paddingRight;
16133					var calculatedPadding = $__default['default'](element).css('padding-right');
16134					$__default['default'](element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px");
16135				}); // Adjust sticky content margin
16136
16137				$__default['default'](stickyContent).each(function (index, element) {
16138					var actualMargin = element.style.marginRight;
16139					var calculatedMargin = $__default['default'](element).css('margin-right');
16140					$__default['default'](element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px");
16141				}); // Adjust body padding
16142
16143				var actualPadding = document.body.style.paddingRight;
16144				var calculatedPadding = $__default['default'](document.body).css('padding-right');
16145				$__default['default'](document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
16146			}
16147
16148			$__default['default'](document.body).addClass(CLASS_NAME_OPEN);
16149		};
16150
16151		_proto._resetScrollbar = function _resetScrollbar() {
16152			// Restore fixed content padding
16153			var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT));
16154			$__default['default'](fixedContent).each(function (index, element) {
16155				var padding = $__default['default'](element).data('padding-right');
16156				$__default['default'](element).removeData('padding-right');
16157				element.style.paddingRight = padding ? padding : '';
16158			}); // Restore sticky content
16159
16160			var elements = [].slice.call(document.querySelectorAll("" + SELECTOR_STICKY_CONTENT));
16161			$__default['default'](elements).each(function (index, element) {
16162				var margin = $__default['default'](element).data('margin-right');
16163
16164				if (typeof margin !== 'undefined') {
16165					$__default['default'](element).css('margin-right', margin).removeData('margin-right');
16166				}
16167			}); // Restore body padding
16168
16169			var padding = $__default['default'](document.body).data('padding-right');
16170			$__default['default'](document.body).removeData('padding-right');
16171			document.body.style.paddingRight = padding ? padding : '';
16172		};
16173
16174		_proto._getScrollbarWidth = function _getScrollbarWidth() {
16175			// thx d.walsh
16176			var scrollDiv = document.createElement('div');
16177			scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
16178			document.body.appendChild(scrollDiv);
16179			var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
16180			document.body.removeChild(scrollDiv);
16181			return scrollbarWidth;
16182		} // Static
16183		;
16184
16185		Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
16186			return this.each(function () {
16187				var data = $__default['default'](this).data(DATA_KEY$5);
16188
16189				var _config = _extends({}, Default$3, $__default['default'](this).data(), typeof config === 'object' && config ? config : {});
16190
16191				if (!data) {
16192					data = new Modal(this, _config);
16193					$__default['default'](this).data(DATA_KEY$5, data);
16194				}
16195
16196				if (typeof config === 'string') {
16197					if (typeof data[config] === 'undefined') {
vendor: 8,660 bytes, lines 16198-16509
16198						throw new TypeError("No method named \"" + config + "\"");
16199					}
16200
16201					data[config](relatedTarget);
16202				} else if (_config.show) {
16203					data.show(relatedTarget);
16204				}
16205			});
16206		};
16207
16208		_createClass(Modal, null, [{
16209			key: "VERSION",
16210			get: function get() {
16211				return VERSION$5;
16212			}
16213		}, {
16214			key: "Default",
16215			get: function get() {
16216				return Default$3;
16217			}
16218		}]);
16219
16220		return Modal;
16221	}();
16222	/**
16223	 * ------------------------------------------------------------------------
16224	 * Data Api implementation
16225	 * ------------------------------------------------------------------------
16226	 */
16227
16228
16229	$__default['default'](document).on(EVENT_CLICK_DATA_API$5, SELECTOR_DATA_TOGGLE$3, function (event) {
16230		var _this11 = this;
16231
16232		var target;
16233		var selector = Util.getSelectorFromElement(this);
16234
16235		if (selector) {
16236			target = document.querySelector(selector);
16237		}
16238
16239		var config = $__default['default'](target).data(DATA_KEY$5) ? 'toggle' : _extends({}, $__default['default'](target).data(), $__default['default'](this).data());
16240
16241		if (this.tagName === 'A' || this.tagName === 'AREA') {
16242			event.preventDefault();
16243		}
16244
16245		var $target = $__default['default'](target).one(EVENT_SHOW$2, function (showEvent) {
16246			if (showEvent.isDefaultPrevented()) {
16247				// Only register focus restorer if modal will actually get shown
16248				return;
16249			}
16250
16251			$target.one(EVENT_HIDDEN$2, function () {
16252				if ($__default['default'](_this11).is(':visible')) {
16253					_this11.focus();
16254				}
16255			});
16256		});
16257
16258		Modal._jQueryInterface.call($__default['default'](target), config, this);
16259	});
16260	/**
16261	 * ------------------------------------------------------------------------
16262	 * jQuery
16263	 * ------------------------------------------------------------------------
16264	 */
16265
16266	$__default['default'].fn[NAME$5] = Modal._jQueryInterface;
16267	$__default['default'].fn[NAME$5].Constructor = Modal;
16268
16269	$__default['default'].fn[NAME$5].noConflict = function () {
16270		$__default['default'].fn[NAME$5] = JQUERY_NO_CONFLICT$5;
16271		return Modal._jQueryInterface;
16272	};
16273
16274	/**
16275	 * --------------------------------------------------------------------------
16276	 * Bootstrap (v4.5.3): tools/sanitizer.js
16277	 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
16278	 * --------------------------------------------------------------------------
16279	 */
16280	var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
16281	var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
16282	var DefaultWhitelist = {
16283		// Global attributes allowed on any supplied element below.
16284		'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
16285		a: ['target', 'href', 'title', 'rel'],
16286		area: [],
16287		b: [],
16288		br: [],
16289		col: [],
16290		code: [],
16291		div: [],
16292		em: [],
16293		hr: [],
16294		h1: [],
16295		h2: [],
16296		h3: [],
16297		h4: [],
16298		h5: [],
16299		h6: [],
16300		i: [],
16301		img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
16302		li: [],
16303		ol: [],
16304		p: [],
16305		pre: [],
16306		s: [],
16307		small: [],
16308		span: [],
16309		sub: [],
16310		sup: [],
16311		strong: [],
16312		u: [],
16313		ul: []
16314	};
16315	/**
16316	 * A pattern that recognizes a commonly useful subset of URLs that are safe.
16317	 *
16318	 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
16319	 */
16320
16321	var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi;
16322	/**
16323	 * A pattern that matches safe data URLs. Only matches image, video and audio types.
16324	 *
16325	 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
16326	 */
16327
16328	var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
16329
16330	function allowedAttribute(attr, allowedAttributeList) {
16331		var attrName = attr.nodeName.toLowerCase();
16332
16333		if (allowedAttributeList.indexOf(attrName) !== -1) {
16334			if (uriAttrs.indexOf(attrName) !== -1) {
16335				return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
16336			}
16337
16338			return true;
16339		}
16340
16341		var regExp = allowedAttributeList.filter(function (attrRegex) {
16342			return attrRegex instanceof RegExp;
16343		}); // Check if a regular expression validates the attribute.
16344
16345		for (var i = 0, len = regExp.length; i < len; i++) {
16346			if (attrName.match(regExp[i])) {
16347				return true;
16348			}
16349		}
16350
16351		return false;
16352	}
16353
16354	function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
16355		if (unsafeHtml.length === 0) {
16356			return unsafeHtml;
16357		}
16358
16359		if (sanitizeFn && typeof sanitizeFn === 'function') {
16360			return sanitizeFn(unsafeHtml);
16361		}
16362
16363		var domParser = new window.DOMParser();
16364		var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
16365		var whitelistKeys = Object.keys(whiteList);
16366		var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
16367
16368		var _loop = function _loop(i, len) {
16369			var el = elements[i];
16370			var elName = el.nodeName.toLowerCase();
16371
16372			if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
16373				el.parentNode.removeChild(el);
16374				return "continue";
16375			}
16376
16377			var attributeList = [].slice.call(el.attributes);
16378			var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
16379			attributeList.forEach(function (attr) {
16380				if (!allowedAttribute(attr, whitelistedAttributes)) {
16381					el.removeAttribute(attr.nodeName);
16382				}
16383			});
16384		};
16385
16386		for (var i = 0, len = elements.length; i < len; i++) {
16387			var _ret = _loop(i);
16388
16389			if (_ret === "continue") continue;
16390		}
16391
16392		return createdDocument.body.innerHTML;
16393	}
16394
16395	/**
16396	 * ------------------------------------------------------------------------
16397	 * Constants
16398	 * ------------------------------------------------------------------------
16399	 */
16400
16401	var NAME$6 = 'tooltip';
16402	var VERSION$6 = '4.5.3';
16403	var DATA_KEY$6 = 'bs.tooltip';
16404	var EVENT_KEY$6 = "." + DATA_KEY$6;
16405	var JQUERY_NO_CONFLICT$6 = $__default['default'].fn[NAME$6];
16406	var CLASS_PREFIX = 'bs-tooltip';
16407	var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
16408	var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
16409	var DefaultType$4 = {
16410		animation: 'boolean',
16411		template: 'string',
16412		title: '(string|element|function)',
16413		trigger: 'string',
16414		delay: '(number|object)',
16415		html: 'boolean',
16416		selector: '(string|boolean)',
16417		placement: '(string|function)',
16418		offset: '(number|string|function)',
16419		container: '(string|element|boolean)',
16420		fallbackPlacement: '(string|array)',
16421		boundary: '(string|element)',
16422		sanitize: 'boolean',
16423		sanitizeFn: '(null|function)',
16424		whiteList: 'object',
16425		popperConfig: '(null|object)'
16426	};
16427	var AttachmentMap = {
16428		AUTO: 'auto',
16429		TOP: 'top',
16430		RIGHT: 'right',
16431		BOTTOM: 'bottom',
16432		LEFT: 'left'
16433	};
16434	var Default$4 = {
16435		animation: true,
16436		template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
16437		trigger: 'hover focus',
16438		title: '',
16439		delay: 0,
16440		html: false,
16441		selector: false,
16442		placement: 'top',
16443		offset: 0,
16444		container: false,
16445		fallbackPlacement: 'flip',
16446		boundary: 'scrollParent',
16447		sanitize: true,
16448		sanitizeFn: null,
16449		whiteList: DefaultWhitelist,
16450		popperConfig: null
16451	};
16452	var HOVER_STATE_SHOW = 'show';
16453	var HOVER_STATE_OUT = 'out';
16454	var Event = {
16455		HIDE: "hide" + EVENT_KEY$6,
16456		HIDDEN: "hidden" + EVENT_KEY$6,
16457		SHOW: "show" + EVENT_KEY$6,
16458		SHOWN: "shown" + EVENT_KEY$6,
16459		INSERTED: "inserted" + EVENT_KEY$6,
16460		CLICK: "click" + EVENT_KEY$6,
16461		FOCUSIN: "focusin" + EVENT_KEY$6,
16462		FOCUSOUT: "focusout" + EVENT_KEY$6,
16463		MOUSEENTER: "mouseenter" + EVENT_KEY$6,
16464		MOUSELEAVE: "mouseleave" + EVENT_KEY$6
16465	};
16466	var CLASS_NAME_FADE$2 = 'fade';
16467	var CLASS_NAME_SHOW$4 = 'show';
16468	var SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
16469	var SELECTOR_ARROW = '.arrow';
16470	var TRIGGER_HOVER = 'hover';
16471	var TRIGGER_FOCUS = 'focus';
16472	var TRIGGER_CLICK = 'click';
16473	var TRIGGER_MANUAL = 'manual';
16474	/**
16475	 * ------------------------------------------------------------------------
16476	 * Class Definition
16477	 * ------------------------------------------------------------------------
16478	 */
16479
16480	var Tooltip = /*#__PURE__*/function () {
16481		function Tooltip(element, config) {
16482			if (typeof Popper === 'undefined') {
16483				throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)');
16484			} // private
16485
16486
16487			this._isEnabled = true;
16488			this._timeout = 0;
16489			this._hoverState = '';
16490			this._activeTrigger = {};
16491			this._popper = null; // Protected
16492
16493			this.element = element;
16494			this.config = this._getConfig(config);
16495			this.tip = null;
16496
16497			this._setListeners();
16498		} // Getters
16499
16500
16501		var _proto = Tooltip.prototype;
16502
16503		// Public
16504		_proto.enable = function enable() {
16505			this._isEnabled = true;
16506		};
16507
16508		_proto.disable = function disable() {
16509			this._isEnabled = false;
vendor: 12,350 bytes, lines 16510-16916
16510		};
16511
16512		_proto.toggleEnabled = function toggleEnabled() {
16513			this._isEnabled = !this._isEnabled;
16514		};
16515
16516		_proto.toggle = function toggle(event) {
16517			if (!this._isEnabled) {
16518				return;
16519			}
16520
16521			if (event) {
16522				var dataKey = this.constructor.DATA_KEY;
16523				var context = $__default['default'](event.currentTarget).data(dataKey);
16524
16525				if (!context) {
16526					context = new this.constructor(event.currentTarget, this._getDelegateConfig());
16527					$__default['default'](event.currentTarget).data(dataKey, context);
16528				}
16529
16530				context._activeTrigger.click = !context._activeTrigger.click;
16531
16532				if (context._isWithActiveTrigger()) {
16533					context._enter(null, context);
16534				} else {
16535					context._leave(null, context);
16536				}
16537			} else {
16538				if ($__default['default'](this.getTipElement()).hasClass(CLASS_NAME_SHOW$4)) {
16539					this._leave(null, this);
16540
16541					return;
16542				}
16543
16544				this._enter(null, this);
16545			}
16546		};
16547
16548		_proto.dispose = function dispose() {
16549			clearTimeout(this._timeout);
16550			$__default['default'].removeData(this.element, this.constructor.DATA_KEY);
16551			$__default['default'](this.element).off(this.constructor.EVENT_KEY);
16552			$__default['default'](this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
16553
16554			if (this.tip) {
16555				$__default['default'](this.tip).remove();
16556			}
16557
16558			this._isEnabled = null;
16559			this._timeout = null;
16560			this._hoverState = null;
16561			this._activeTrigger = null;
16562
16563			if (this._popper) {
16564				this._popper.destroy();
16565			}
16566
16567			this._popper = null;
16568			this.element = null;
16569			this.config = null;
16570			this.tip = null;
16571		};
16572
16573		_proto.show = function show() {
16574			var _this = this;
16575
16576			if ($__default['default'](this.element).css('display') === 'none') {
16577				throw new Error('Please use show on visible elements');
16578			}
16579
16580			var showEvent = $__default['default'].Event(this.constructor.Event.SHOW);
16581
16582			if (this.isWithContent() && this._isEnabled) {
16583				$__default['default'](this.element).trigger(showEvent);
16584				var shadowRoot = Util.findShadowRoot(this.element);
16585				var isInTheDom = $__default['default'].contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
16586
16587				if (showEvent.isDefaultPrevented() || !isInTheDom) {
16588					return;
16589				}
16590
16591				var tip = this.getTipElement();
16592				var tipId = Util.getUID(this.constructor.NAME);
16593				tip.setAttribute('id', tipId);
16594				this.element.setAttribute('aria-describedby', tipId);
16595				this.setContent();
16596
16597				if (this.config.animation) {
16598					$__default['default'](tip).addClass(CLASS_NAME_FADE$2);
16599				}
16600
16601				var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
16602
16603				var attachment = this._getAttachment(placement);
16604
16605				this.addAttachmentClass(attachment);
16606
16607				var container = this._getContainer();
16608
16609				$__default['default'](tip).data(this.constructor.DATA_KEY, this);
16610
16611				if (!$__default['default'].contains(this.element.ownerDocument.documentElement, this.tip)) {
16612					$__default['default'](tip).appendTo(container);
16613				}
16614
16615				$__default['default'](this.element).trigger(this.constructor.Event.INSERTED);
16616				// this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment));
16617				$__default['default'](tip).addClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we add extra
16618				// empty mouseover listeners to the body's immediate children;
16619				// only needed because of broken event delegation on iOS
16620				// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
16621
16622				if ('ontouchstart' in document.documentElement) {
16623					$__default['default'](document.body).children().on('mouseover', null, $__default['default'].noop);
16624				}
16625
16626				var complete = function complete() {
16627					if (_this.config.animation) {
16628						_this._fixTransition();
16629					}
16630
16631					var prevHoverState = _this._hoverState;
16632					_this._hoverState = null;
16633					$__default['default'](_this.element).trigger(_this.constructor.Event.SHOWN);
16634
16635					if (prevHoverState === HOVER_STATE_OUT) {
16636						_this._leave(null, _this);
16637					}
16638				};
16639
16640				if ($__default['default'](this.tip).hasClass(CLASS_NAME_FADE$2)) {
16641					var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
16642					$__default['default'](this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
16643				} else {
16644					complete();
16645				}
16646			}
16647		};
16648
16649		_proto.hide = function hide(callback) {
16650			var _this2 = this;
16651
16652			var tip = this.getTipElement();
16653			var hideEvent = $__default['default'].Event(this.constructor.Event.HIDE);
16654
16655			var complete = function complete() {
16656				if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
16657					tip.parentNode.removeChild(tip);
16658				}
16659
16660				_this2._cleanTipClass();
16661
16662				_this2.element.removeAttribute('aria-describedby');
16663
16664				$__default['default'](_this2.element).trigger(_this2.constructor.Event.HIDDEN);
16665
16666				if (_this2._popper !== null) {
16667					_this2._popper.destroy();
16668				}
16669
16670				if (callback) {
16671					callback();
16672				}
16673			};
16674
16675			$__default['default'](this.element).trigger(hideEvent);
16676
16677			if (hideEvent.isDefaultPrevented()) {
16678				return;
16679			}
16680
16681			$__default['default'](tip).removeClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we remove the extra
16682			// empty mouseover listeners we added for iOS support
16683
16684			if ('ontouchstart' in document.documentElement) {
16685				$__default['default'](document.body).children().off('mouseover', null, $__default['default'].noop);
16686			}
16687
16688			this._activeTrigger[TRIGGER_CLICK] = false;
16689			this._activeTrigger[TRIGGER_FOCUS] = false;
16690			this._activeTrigger[TRIGGER_HOVER] = false;
16691
16692			if ($__default['default'](this.tip).hasClass(CLASS_NAME_FADE$2)) {
16693				var transitionDuration = Util.getTransitionDurationFromElement(tip);
16694				$__default['default'](tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
16695			} else {
16696				complete();
16697			}
16698
16699			this._hoverState = '';
16700		};
16701
16702		_proto.update = function update() {
16703			if (this._popper !== null) {
16704				this._popper.scheduleUpdate();
16705			}
16706		} // Protected
16707		;
16708
16709		_proto.isWithContent = function isWithContent() {
16710			return Boolean(this.getTitle());
16711		};
16712
16713		_proto.addAttachmentClass = function addAttachmentClass(attachment) {
16714			$__default['default'](this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
16715		};
16716
16717		_proto.getTipElement = function getTipElement() {
16718			this.tip = this.tip || $__default['default'](this.config.template)[0];
16719			return this.tip;
16720		};
16721
16722		_proto.setContent = function setContent() {
16723			var tip = this.getTipElement();
16724			this.setElementContent($__default['default'](tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle());
16725			$__default['default'](tip).removeClass(CLASS_NAME_FADE$2 + " " + CLASS_NAME_SHOW$4);
16726		};
16727
16728		_proto.setElementContent = function setElementContent($element, content) {
16729			if (typeof content === 'object' && (content.nodeType || content.jquery)) {
16730				// Content is a DOM node or a jQuery
16731				if (this.config.html) {
16732					if (!$__default['default'](content).parent().is($element)) {
16733						$element.empty().append(content);
16734					}
16735				} else {
16736					$element.text($__default['default'](content).text());
16737				}
16738
16739				return;
16740			}
16741
16742			if (this.config.html) {
16743				if (this.config.sanitize) {
16744					content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
16745				}
16746
16747				$element.html(content);
16748			} else {
16749				$element.text(content);
16750			}
16751		};
16752
16753		_proto.getTitle = function getTitle() {
16754			var title = this.element.getAttribute('data-original-title');
16755
16756			if (!title) {
16757				title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
16758			}
16759
16760			return title;
16761		} // Private
16762		;
16763
16764		_proto._getPopperConfig = function _getPopperConfig(attachment) {
16765			var _this3 = this;
16766
16767			var defaultBsConfig = {
16768				placement: attachment,
16769				modifiers: {
16770					offset: this._getOffset(),
16771					flip: {
16772						behavior: this.config.fallbackPlacement
16773					},
16774					arrow: {
16775						element: SELECTOR_ARROW
16776					},
16777					preventOverflow: {
16778						boundariesElement: this.config.boundary
16779					}
16780				},
16781				onCreate: function onCreate(data) {
16782					if (data.originalPlacement !== data.placement) {
16783						_this3._handlePopperPlacementChange(data);
16784					}
16785				},
16786				onUpdate: function onUpdate(data) {
16787					return _this3._handlePopperPlacementChange(data);
16788				}
16789			};
16790			return _extends({}, defaultBsConfig, this.config.popperConfig);
16791		};
16792
16793		_proto._getOffset = function _getOffset() {
16794			var _this4 = this;
16795
16796			var offset = {};
16797
16798			if (typeof this.config.offset === 'function') {
16799				offset.fn = function (data) {
16800					data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element) || {});
16801					return data;
16802				};
16803			} else {
16804				offset.offset = this.config.offset;
16805			}
16806
16807			return offset;
16808		};
16809
16810		_proto._getContainer = function _getContainer() {
16811			if (this.config.container === false) {
16812				return document.body;
16813			}
16814
16815			if (Util.isElement(this.config.container)) {
16816				return $__default['default'](this.config.container);
16817			}
16818
16819			return $__default['default'](document).find(this.config.container);
16820		};
16821
16822		_proto._getAttachment = function _getAttachment(placement) {
16823			return AttachmentMap[placement.toUpperCase()];
16824		};
16825
16826		_proto._setListeners = function _setListeners() {
16827			var _this5 = this;
16828
16829			var triggers = this.config.trigger.split(' ');
16830			triggers.forEach(function (trigger) {
16831				if (trigger === 'click') {
16832					$__default['default'](_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
16833						return _this5.toggle(event);
16834					});
16835				} else if (trigger !== TRIGGER_MANUAL) {
16836					var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
16837					var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
16838					$__default['default'](_this5.element).on(eventIn, _this5.config.selector, function (event) {
16839						return _this5._enter(event);
16840					}).on(eventOut, _this5.config.selector, function (event) {
16841						return _this5._leave(event);
16842					});
16843				}
16844			});
16845
16846			this._hideModalHandler = function () {
16847				if (_this5.element) {
16848					_this5.hide();
16849				}
16850			};
16851
16852			$__default['default'](this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
16853
16854			if (this.config.selector) {
16855				this.config = _extends({}, this.config, {
16856					trigger: 'manual',
16857					selector: ''
16858				});
16859			} else {
16860				this._fixTitle();
16861			}
16862		};
16863
16864		_proto._fixTitle = function _fixTitle() {
16865			var titleType = typeof this.element.getAttribute('data-original-title');
16866
16867			if (this.element.getAttribute('title') || titleType !== 'string') {
16868				this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
16869				this.element.setAttribute('title', '');
16870			}
16871		};
16872
16873		_proto._enter = function _enter(event, context) {
16874			var dataKey = this.constructor.DATA_KEY;
16875			context = context || $__default['default'](event.currentTarget).data(dataKey);
16876
16877			if (!context) {
16878				context = new this.constructor(event.currentTarget, this._getDelegateConfig());
16879				$__default['default'](event.currentTarget).data(dataKey, context);
16880			}
16881
16882			if (event) {
16883				context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
16884			}
16885
16886			if ($__default['default'](context.getTipElement()).hasClass(CLASS_NAME_SHOW$4) || context._hoverState === HOVER_STATE_SHOW) {
16887				context._hoverState = HOVER_STATE_SHOW;
16888				return;
16889			}
16890
16891			clearTimeout(context._timeout);
16892			context._hoverState = HOVER_STATE_SHOW;
16893
16894			if (!context.config.delay || !context.config.delay.show) {
16895				context.show();
16896				return;
16897			}
16898
16899			context._timeout = setTimeout(function () {
16900				if (context._hoverState === HOVER_STATE_SHOW) {
16901					context.show();
16902				}
16903			}, context.config.delay.show);
16904		};
16905
16906		_proto._leave = function _leave(event, context) {
16907			var dataKey = this.constructor.DATA_KEY;
16908			context = context || $__default['default'](event.currentTarget).data(dataKey);
16909
16910			if (!context) {
16911				context = new this.constructor(event.currentTarget, this._getDelegateConfig());
16912				$__default['default'](event.currentTarget).data(dataKey, context);
16913			}
16914
16915			if (event) {
16916				context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false;
vendor: 10,013 bytes, lines 16917-17312
16917			}
16918
16919			if (context._isWithActiveTrigger()) {
16920				return;
16921			}
16922
16923			clearTimeout(context._timeout);
16924			context._hoverState = HOVER_STATE_OUT;
16925
16926			if (!context.config.delay || !context.config.delay.hide) {
16927				context.hide();
16928				return;
16929			}
16930
16931			context._timeout = setTimeout(function () {
16932				if (context._hoverState === HOVER_STATE_OUT) {
16933					context.hide();
16934				}
16935			}, context.config.delay.hide);
16936		};
16937
16938		_proto._isWithActiveTrigger = function _isWithActiveTrigger() {
16939			for (var trigger in this._activeTrigger) {
16940				if (this._activeTrigger[trigger]) {
16941					return true;
16942				}
16943			}
16944
16945			return false;
16946		};
16947
16948		_proto._getConfig = function _getConfig(config) {
16949			var dataAttributes = $__default['default'](this.element).data();
16950			Object.keys(dataAttributes).forEach(function (dataAttr) {
16951				if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
16952					delete dataAttributes[dataAttr];
16953				}
16954			});
16955			config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
16956
16957			if (typeof config.delay === 'number') {
16958				config.delay = {
16959					show: config.delay,
16960					hide: config.delay
16961				};
16962			}
16963
16964			if (typeof config.title === 'number') {
16965				config.title = config.title.toString();
16966			}
16967
16968			if (typeof config.content === 'number') {
16969				config.content = config.content.toString();
16970			}
16971
16972			Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType);
16973
16974			if (config.sanitize) {
16975				config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
16976			}
16977
16978			return config;
16979		};
16980
16981		_proto._getDelegateConfig = function _getDelegateConfig() {
16982			var config = {};
16983
16984			if (this.config) {
16985				for (var key in this.config) {
16986					if (this.constructor.Default[key] !== this.config[key]) {
16987						config[key] = this.config[key];
16988					}
16989				}
16990			}
16991
16992			return config;
16993		};
16994
16995		_proto._cleanTipClass = function _cleanTipClass() {
16996			var $tip = $__default['default'](this.getTipElement());
16997			var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
16998
16999			if (tabClass !== null && tabClass.length) {
17000				$tip.removeClass(tabClass.join(''));
17001			}
17002		};
17003
17004		_proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
17005			this.tip = popperData.instance.popper;
17006
17007			this._cleanTipClass();
17008
17009			this.addAttachmentClass(this._getAttachment(popperData.placement));
17010		};
17011
17012		_proto._fixTransition = function _fixTransition() {
17013			var tip = this.getTipElement();
17014			var initConfigAnimation = this.config.animation;
17015
17016			if (tip.getAttribute('x-placement') !== null) {
17017				return;
17018			}
17019
17020			$__default['default'](tip).removeClass(CLASS_NAME_FADE$2);
17021			this.config.animation = false;
17022			this.hide();
17023			this.show();
17024			this.config.animation = initConfigAnimation;
17025		} // Static
17026		;
17027
17028		Tooltip._jQueryInterface = function _jQueryInterface(config) {
17029			return this.each(function () {
17030				var $element = $__default['default'](this);
17031				var data = $element.data(DATA_KEY$6);
17032
17033				var _config = typeof config === 'object' && config;
17034
17035				if (!data && /dispose|hide/.test(config)) {
17036					return;
17037				}
17038
17039				if (!data) {
17040					data = new Tooltip(this, _config);
17041					$element.data(DATA_KEY$6, data);
17042				}
17043
17044				if (typeof config === 'string') {
17045					if (typeof data[config] === 'undefined') {
17046						throw new TypeError("No method named \"" + config + "\"");
17047					}
17048
17049					data[config]();
17050				}
17051			});
17052		};
17053
17054		_createClass(Tooltip, null, [{
17055			key: "VERSION",
17056			get: function get() {
17057				return VERSION$6;
17058			}
17059		}, {
17060			key: "Default",
17061			get: function get() {
17062				return Default$4;
17063			}
17064		}, {
17065			key: "NAME",
17066			get: function get() {
17067				return NAME$6;
17068			}
17069		}, {
17070			key: "DATA_KEY",
17071			get: function get() {
17072				return DATA_KEY$6;
17073			}
17074		}, {
17075			key: "Event",
17076			get: function get() {
17077				return Event;
17078			}
17079		}, {
17080			key: "EVENT_KEY",
17081			get: function get() {
17082				return EVENT_KEY$6;
17083			}
17084		}, {
17085			key: "DefaultType",
17086			get: function get() {
17087				return DefaultType$4;
17088			}
17089		}]);
17090
17091		return Tooltip;
17092	}();
17093	/**
17094	 * ------------------------------------------------------------------------
17095	 * jQuery
17096	 * ------------------------------------------------------------------------
17097	 */
17098
17099
17100	$__default['default'].fn[NAME$6] = Tooltip._jQueryInterface;
17101	$__default['default'].fn[NAME$6].Constructor = Tooltip;
17102
17103	$__default['default'].fn[NAME$6].noConflict = function () {
17104		$__default['default'].fn[NAME$6] = JQUERY_NO_CONFLICT$6;
17105		return Tooltip._jQueryInterface;
17106	};
17107
17108	/**
17109	 * ------------------------------------------------------------------------
17110	 * Constants
17111	 * ------------------------------------------------------------------------
17112	 */
17113
17114	var NAME$7 = 'popover';
17115	var VERSION$7 = '4.5.3';
17116	var DATA_KEY$7 = 'bs.popover';
17117	var EVENT_KEY$7 = "." + DATA_KEY$7;
17118	var JQUERY_NO_CONFLICT$7 = $__default['default'].fn[NAME$7];
17119	var CLASS_PREFIX$1 = 'bs-popover';
17120	var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
17121
17122	var Default$5 = _extends({}, Tooltip.Default, {
17123		placement: 'right',
17124		trigger: 'click',
17125		content: '',
17126		template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
17127	});
17128
17129	var DefaultType$5 = _extends({}, Tooltip.DefaultType, {
17130		content: '(string|element|function)'
17131	});
17132
17133	var CLASS_NAME_FADE$3 = 'fade';
17134	var CLASS_NAME_SHOW$5 = 'show';
17135	var SELECTOR_TITLE = '.popover-header';
17136	var SELECTOR_CONTENT = '.popover-body';
17137	var Event$1 = {
17138		HIDE: "hide" + EVENT_KEY$7,
17139		HIDDEN: "hidden" + EVENT_KEY$7,
17140		SHOW: "show" + EVENT_KEY$7,
17141		SHOWN: "shown" + EVENT_KEY$7,
17142		INSERTED: "inserted" + EVENT_KEY$7,
17143		CLICK: "click" + EVENT_KEY$7,
17144		FOCUSIN: "focusin" + EVENT_KEY$7,
17145		FOCUSOUT: "focusout" + EVENT_KEY$7,
17146		MOUSEENTER: "mouseenter" + EVENT_KEY$7,
17147		MOUSELEAVE: "mouseleave" + EVENT_KEY$7
17148	};
17149	/**
17150	 * ------------------------------------------------------------------------
17151	 * Class Definition
17152	 * ------------------------------------------------------------------------
17153	 */
17154
17155	var Popover = /*#__PURE__*/function (_Tooltip) {
17156		_inheritsLoose(Popover, _Tooltip);
17157
17158		function Popover() {
17159			return _Tooltip.apply(this, arguments) || this;
17160		}
17161
17162		var _proto = Popover.prototype;
17163
17164		// Overrides
17165		_proto.isWithContent = function isWithContent() {
17166			return this.getTitle() || this._getContent();
17167		};
17168
17169		_proto.addAttachmentClass = function addAttachmentClass(attachment) {
17170			$__default['default'](this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment);
17171		};
17172
17173		_proto.getTipElement = function getTipElement() {
17174			this.tip = this.tip || $__default['default'](this.config.template)[0];
17175			return this.tip;
17176		};
17177
17178		_proto.setContent = function setContent() {
17179			var $tip = $__default['default'](this.getTipElement()); // We use append for html objects to maintain js events
17180
17181			this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle());
17182
17183			var content = this._getContent();
17184
17185			if (typeof content === 'function') {
17186				content = content.call(this.element);
17187			}
17188
17189			this.setElementContent($tip.find(SELECTOR_CONTENT), content);
17190			$tip.removeClass(CLASS_NAME_FADE$3 + " " + CLASS_NAME_SHOW$5);
17191		} // Private
17192		;
17193
17194		_proto._getContent = function _getContent() {
17195			return this.element.getAttribute('data-content') || this.config.content;
17196		};
17197
17198		_proto._cleanTipClass = function _cleanTipClass() {
17199			var $tip = $__default['default'](this.getTipElement());
17200			var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1);
17201
17202			if (tabClass !== null && tabClass.length > 0) {
17203				$tip.removeClass(tabClass.join(''));
17204			}
17205		} // Static
17206		;
17207
17208		Popover._jQueryInterface = function _jQueryInterface(config) {
17209			return this.each(function () {
17210				var data = $__default['default'](this).data(DATA_KEY$7);
17211
17212				var _config = typeof config === 'object' ? config : null;
17213
17214				if (!data && /dispose|hide/.test(config)) {
17215					return;
17216				}
17217
17218				if (!data) {
17219					data = new Popover(this, _config);
17220					$__default['default'](this).data(DATA_KEY$7, data);
17221				}
17222
17223				if (typeof config === 'string') {
17224					if (typeof data[config] === 'undefined') {
17225						throw new TypeError("No method named \"" + config + "\"");
17226					}
17227
17228					data[config]();
17229				}
17230			});
17231		};
17232
17233		_createClass(Popover, null, [{
17234			key: "VERSION",
17235			// Getters
17236			get: function get() {
17237				return VERSION$7;
17238			}
17239		}, {
17240			key: "Default",
17241			get: function get() {
17242				return Default$5;
17243			}
17244		}, {
17245			key: "NAME",
17246			get: function get() {
17247				return NAME$7;
17248			}
17249		}, {
17250			key: "DATA_KEY",
17251			get: function get() {
17252				return DATA_KEY$7;
17253			}
17254		}, {
17255			key: "Event",
17256			get: function get() {
17257				return Event$1;
17258			}
17259		}, {
17260			key: "EVENT_KEY",
17261			get: function get() {
17262				return EVENT_KEY$7;
17263			}
17264		}, {
17265			key: "DefaultType",
17266			get: function get() {
17267				return DefaultType$5;
17268			}
17269		}]);
17270
17271		return Popover;
17272	}(Tooltip);
17273	/**
17274	 * ------------------------------------------------------------------------
17275	 * jQuery
17276	 * ------------------------------------------------------------------------
17277	 */
17278
17279
17280	$__default['default'].fn[NAME$7] = Popover._jQueryInterface;
17281	$__default['default'].fn[NAME$7].Constructor = Popover;
17282
17283	$__default['default'].fn[NAME$7].noConflict = function () {
17284		$__default['default'].fn[NAME$7] = JQUERY_NO_CONFLICT$7;
17285		return Popover._jQueryInterface;
17286	};
17287
17288	/**
17289	 * ------------------------------------------------------------------------
17290	 * Constants
17291	 * ------------------------------------------------------------------------
17292	 */
17293
17294	var NAME$8 = 'scrollspy';
17295	var VERSION$8 = '4.5.3';
17296	var DATA_KEY$8 = 'bs.scrollspy';
17297	var EVENT_KEY$8 = "." + DATA_KEY$8;
17298	var DATA_API_KEY$6 = '.data-api';
17299	var JQUERY_NO_CONFLICT$8 = $__default['default'].fn[NAME$8];
17300	var Default$6 = {
17301		offset: 10,
17302		method: 'auto',
17303		target: ''
17304	};
17305	var DefaultType$6 = {
17306		offset: 'number',
17307		method: 'string',
17308		target: '(string|element)'
17309	};
17310	var EVENT_ACTIVATE = "activate" + EVENT_KEY$8;
17311	var EVENT_SCROLL = "scroll" + EVENT_KEY$8;
17312	var EVENT_LOAD_DATA_API$2 = "load" + EVENT_KEY$8 + DATA_API_KEY$6;
vendor: 5,504 bytes, lines 17313-17486
17313	var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
17314	var CLASS_NAME_ACTIVE$2 = 'active';
17315	var SELECTOR_DATA_SPY = '[data-spy="scroll"]';
17316	var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
17317	var SELECTOR_NAV_LINKS = '.nav-link';
17318	var SELECTOR_NAV_ITEMS = '.nav-item';
17319	var SELECTOR_LIST_ITEMS = '.list-group-item';
17320	var SELECTOR_DROPDOWN = '.dropdown';
17321	var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item';
17322	var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
17323	var METHOD_OFFSET = 'offset';
17324	var METHOD_POSITION = 'position';
17325	/**
17326	 * ------------------------------------------------------------------------
17327	 * Class Definition
17328	 * ------------------------------------------------------------------------
17329	 */
17330
17331	var ScrollSpy = /*#__PURE__*/function () {
17332		function ScrollSpy(element, config) {
17333			var _this = this;
17334
17335			this._element = element;
17336			this._scrollElement = element.tagName === 'BODY' ? window : element;
17337			this._config = this._getConfig(config);
17338			this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS);
17339			this._offsets = [];
17340			this._targets = [];
17341			this._activeTarget = null;
17342			this._scrollHeight = 0;
17343			$__default['default'](this._scrollElement).on(EVENT_SCROLL, function (event) {
17344				return _this._process(event);
17345			});
17346			this.refresh();
17347
17348			this._process();
17349		} // Getters
17350
17351
17352		var _proto = ScrollSpy.prototype;
17353
17354		// Public
17355		_proto.refresh = function refresh() {
17356			var _this2 = this;
17357
17358			var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
17359			var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
17360			var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
17361			this._offsets = [];
17362			this._targets = [];
17363			this._scrollHeight = this._getScrollHeight();
17364			var targets = [].slice.call(document.querySelectorAll(this._selector));
17365			targets.map(function (element) {
17366				var target;
17367				var targetSelector = Util.getSelectorFromElement(element);
17368
17369				if (targetSelector) {
17370					target = document.querySelector(targetSelector);
17371				}
17372
17373				if (target) {
17374					var targetBCR = target.getBoundingClientRect();
17375
17376					if (targetBCR.width || targetBCR.height) {
17377						// TODO (fat): remove sketch reliance on jQuery position/offset
17378						return [$__default['default'](target)[offsetMethod]().top + offsetBase, targetSelector];
17379					}
17380				}
17381
17382				return null;
17383			}).filter(function (item) {
17384				return item;
17385			}).sort(function (a, b) {
17386				return a[0] - b[0];
17387			}).forEach(function (item) {
17388				_this2._offsets.push(item[0]);
17389
17390				_this2._targets.push(item[1]);
17391			});
17392		};
17393
17394		_proto.dispose = function dispose() {
17395			$__default['default'].removeData(this._element, DATA_KEY$8);
17396			$__default['default'](this._scrollElement).off(EVENT_KEY$8);
17397			this._element = null;
17398			this._scrollElement = null;
17399			this._config = null;
17400			this._selector = null;
17401			this._offsets = null;
17402			this._targets = null;
17403			this._activeTarget = null;
17404			this._scrollHeight = null;
17405		} // Private
17406		;
17407
17408		_proto._getConfig = function _getConfig(config) {
17409			config = _extends({}, Default$6, typeof config === 'object' && config ? config : {});
17410
17411			if (typeof config.target !== 'string' && Util.isElement(config.target)) {
17412				var id = $__default['default'](config.target).attr('id');
17413
17414				if (!id) {
17415					id = Util.getUID(NAME$8);
17416					$__default['default'](config.target).attr('id', id);
17417				}
17418
17419				config.target = "#" + id;
17420			}
17421
17422			Util.typeCheckConfig(NAME$8, config, DefaultType$6);
17423			return config;
17424		};
17425
17426		_proto._getScrollTop = function _getScrollTop() {
17427			return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
17428		};
17429
17430		_proto._getScrollHeight = function _getScrollHeight() {
17431			return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
17432		};
17433
17434		_proto._getOffsetHeight = function _getOffsetHeight() {
17435			return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
17436		};
17437
17438		_proto._process = function _process() {
17439			var scrollTop = this._getScrollTop() + this._config.offset;
17440
17441			var scrollHeight = this._getScrollHeight();
17442
17443			var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
17444
17445			if (this._scrollHeight !== scrollHeight) {
17446				this.refresh();
17447			}
17448
17449			if (scrollTop >= maxScroll) {
17450				var target = this._targets[this._targets.length - 1];
17451
17452				if (this._activeTarget !== target) {
17453					this._activate(target);
17454				}
17455
17456				return;
17457			}
17458
17459			if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
17460				this._activeTarget = null;
17461
17462				this._clear();
17463
17464				return;
17465			}
17466
17467			for (var i = this._offsets.length; i--;) {
17468				var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
17469
17470				if (isActiveTarget) {
17471					this._activate(this._targets[i]);
17472				}
17473			}
17474		};
17475
17476		_proto._activate = function _activate(target) {
17477			this._activeTarget = target;
17478
17479			this._clear();
17480
17481			var queries = this._selector.split(',').map(function (selector) {
17482				return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
17483			});
17484
17485			var $link = $__default['default']([].slice.call(document.querySelectorAll(queries.join(','))));
17486
vendor: 5,115 bytes, lines 17487-17637
17487			if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
17488				$link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE$2);
17489				$link.addClass(CLASS_NAME_ACTIVE$2);
17490			} else {
17491				// Set triggered link as active
17492				$link.addClass(CLASS_NAME_ACTIVE$2); // Set triggered links parents as active
17493				// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
17494
17495				$link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_LINKS + ", " + SELECTOR_LIST_ITEMS).addClass(CLASS_NAME_ACTIVE$2); // Handle special case when .nav-link is inside .nav-item
17496
17497				$link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_ITEMS).children(SELECTOR_NAV_LINKS).addClass(CLASS_NAME_ACTIVE$2);
17498			}
17499
17500			$__default['default'](this._scrollElement).trigger(EVENT_ACTIVATE, {
17501				relatedTarget: target
17502			});
17503		};
17504
17505		_proto._clear = function _clear() {
17506			[].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
17507				return node.classList.contains(CLASS_NAME_ACTIVE$2);
17508			}).forEach(function (node) {
17509				return node.classList.remove(CLASS_NAME_ACTIVE$2);
17510			});
17511		} // Static
17512		;
17513
17514		ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
17515			return this.each(function () {
17516				var data = $__default['default'](this).data(DATA_KEY$8);
17517
17518				var _config = typeof config === 'object' && config;
17519
17520				if (!data) {
17521					data = new ScrollSpy(this, _config);
17522					$__default['default'](this).data(DATA_KEY$8, data);
17523				}
17524
17525				if (typeof config === 'string') {
17526					if (typeof data[config] === 'undefined') {
17527						throw new TypeError("No method named \"" + config + "\"");
17528					}
17529
17530					data[config]();
17531				}
17532			});
17533		};
17534
17535		_createClass(ScrollSpy, null, [{
17536			key: "VERSION",
17537			get: function get() {
17538				return VERSION$8;
17539			}
17540		}, {
17541			key: "Default",
17542			get: function get() {
17543				return Default$6;
17544			}
17545		}]);
17546
17547		return ScrollSpy;
17548	}();
17549	/**
17550	 * ------------------------------------------------------------------------
17551	 * Data Api implementation
17552	 * ------------------------------------------------------------------------
17553	 */
17554
17555
17556	$__default['default'](window).on(EVENT_LOAD_DATA_API$2, function () {
17557		var scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY));
17558		var scrollSpysLength = scrollSpys.length;
17559
17560		for (var i = scrollSpysLength; i--;) {
17561			var $spy = $__default['default'](scrollSpys[i]);
17562
17563			ScrollSpy._jQueryInterface.call($spy, $spy.data());
17564		}
17565	});
17566	/**
17567	 * ------------------------------------------------------------------------
17568	 * jQuery
17569	 * ------------------------------------------------------------------------
17570	 */
17571
17572	$__default['default'].fn[NAME$8] = ScrollSpy._jQueryInterface;
17573	$__default['default'].fn[NAME$8].Constructor = ScrollSpy;
17574
17575	$__default['default'].fn[NAME$8].noConflict = function () {
17576		$__default['default'].fn[NAME$8] = JQUERY_NO_CONFLICT$8;
17577		return ScrollSpy._jQueryInterface;
17578	};
17579
17580	/**
17581	 * ------------------------------------------------------------------------
17582	 * Constants
17583	 * ------------------------------------------------------------------------
17584	 */
17585
17586	var NAME$9 = 'tab';
17587	var VERSION$9 = '4.5.3';
17588	var DATA_KEY$9 = 'bs.tab';
17589	var EVENT_KEY$9 = "." + DATA_KEY$9;
17590	var DATA_API_KEY$7 = '.data-api';
17591	var JQUERY_NO_CONFLICT$9 = $__default['default'].fn[NAME$9];
17592	var EVENT_HIDE$3 = "hide" + EVENT_KEY$9;
17593	var EVENT_HIDDEN$3 = "hidden" + EVENT_KEY$9;
17594	var EVENT_SHOW$3 = "show" + EVENT_KEY$9;
17595	var EVENT_SHOWN$3 = "shown" + EVENT_KEY$9;
17596	var EVENT_CLICK_DATA_API$6 = "click" + EVENT_KEY$9 + DATA_API_KEY$7;
17597	var CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';
17598	var CLASS_NAME_ACTIVE$3 = 'active';
17599	var CLASS_NAME_DISABLED$1 = 'disabled';
17600	var CLASS_NAME_FADE$4 = 'fade';
17601	var CLASS_NAME_SHOW$6 = 'show';
17602	var SELECTOR_DROPDOWN$1 = '.dropdown';
17603	var SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';
17604	var SELECTOR_ACTIVE$2 = '.active';
17605	var SELECTOR_ACTIVE_UL = '> li > .active';
17606	var SELECTOR_DATA_TOGGLE$4 = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]';
17607	var SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
17608	var SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active';
17609	/**
17610	 * ------------------------------------------------------------------------
17611	 * Class Definition
17612	 * ------------------------------------------------------------------------
17613	 */
17614
17615	var Tab = /*#__PURE__*/function () {
17616		function Tab(element) {
17617			this._element = element;
17618		} // Getters
17619
17620
17621		var _proto = Tab.prototype;
17622
17623		// Public
17624		_proto.show = function show() {
17625			var _this = this;
17626
17627			if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $__default['default'](this._element).hasClass(CLASS_NAME_ACTIVE$3) || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED$1)) {
17628				return;
17629			}
17630
17631			var target;
17632			var previous;
17633			var listElement = $__default['default'](this._element).closest(SELECTOR_NAV_LIST_GROUP$1)[0];
17634			var selector = Util.getSelectorFromElement(this._element);
17635
17636			if (listElement) {
17637				var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE$2;
vendor: 2,395 bytes, lines 17638-17710
17638				previous = $__default['default'].makeArray($__default['default'](listElement).find(itemSelector));
17639				previous = previous[previous.length - 1];
17640			}
17641
17642			var hideEvent = $__default['default'].Event(EVENT_HIDE$3, {
17643				relatedTarget: this._element
17644			});
17645			var showEvent = $__default['default'].Event(EVENT_SHOW$3, {
17646				relatedTarget: previous
17647			});
17648
17649			if (previous) {
17650				$__default['default'](previous).trigger(hideEvent);
17651			}
17652
17653			$__default['default'](this._element).trigger(showEvent);
17654
17655			if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
17656				return;
17657			}
17658
17659			if (selector) {
17660				target = document.querySelector(selector);
17661			}
17662
17663			this._activate(this._element, listElement);
17664
17665			var complete = function complete() {
17666				var hiddenEvent = $__default['default'].Event(EVENT_HIDDEN$3, {
17667					relatedTarget: _this._element
17668				});
17669				var shownEvent = $__default['default'].Event(EVENT_SHOWN$3, {
17670					relatedTarget: previous
17671				});
17672				$__default['default'](previous).trigger(hiddenEvent);
17673				$__default['default'](_this._element).trigger(shownEvent);
17674			};
17675
17676			if (target) {
17677				this._activate(target, target.parentNode, complete);
17678			} else {
17679				complete();
17680			}
17681		};
17682
17683		_proto.dispose = function dispose() {
17684			$__default['default'].removeData(this._element, DATA_KEY$9);
17685			this._element = null;
17686		} // Private
17687		;
17688
17689		_proto._activate = function _activate(element, container, callback) {
17690			var _this2 = this;
17691
17692			var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $__default['default'](container).find(SELECTOR_ACTIVE_UL) : $__default['default'](container).children(SELECTOR_ACTIVE$2);
17693			var active = activeElements[0];
17694			var isTransitioning = callback && active && $__default['default'](active).hasClass(CLASS_NAME_FADE$4);
17695
17696			var complete = function complete() {
17697				return _this2._transitionComplete(element, active, callback);
17698			};
17699
17700			if (active && isTransitioning) {
17701				var transitionDuration = Util.getTransitionDurationFromElement(active);
17702				$__default['default'](active).removeClass(CLASS_NAME_SHOW$6).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
17703			} else {
17704				complete();
17705			}
17706		};
17707
17708		_proto._transitionComplete = function _transitionComplete(element, active, callback) {
17709			if (active) {
17710				$__default['default'](active).removeClass(CLASS_NAME_ACTIVE$3);
vendor: 7,444 bytes, lines 17711-17981
17711				var dropdownChild = $__default['default'](active.parentNode).find(SELECTOR_DROPDOWN_ACTIVE_CHILD)[0];
17712
17713				if (dropdownChild) {
17714					$__default['default'](dropdownChild).removeClass(CLASS_NAME_ACTIVE$3);
17715				}
17716
17717				if (active.getAttribute('role') === 'tab') {
17718					active.setAttribute('aria-selected', false);
17719				}
17720			}
17721
17722			$__default['default'](element).addClass(CLASS_NAME_ACTIVE$3);
17723
17724			if (element.getAttribute('role') === 'tab') {
17725				element.setAttribute('aria-selected', true);
17726			}
17727
17728			Util.reflow(element);
17729
17730			if (element.classList.contains(CLASS_NAME_FADE$4)) {
17731				element.classList.add(CLASS_NAME_SHOW$6);
17732			}
17733
17734			if (element.parentNode && $__default['default'](element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {
17735				var dropdownElement = $__default['default'](element).closest(SELECTOR_DROPDOWN$1)[0];
17736
17737				if (dropdownElement) {
17738					var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE$1));
17739					$__default['default'](dropdownToggleList).addClass(CLASS_NAME_ACTIVE$3);
17740				}
17741
17742				element.setAttribute('aria-expanded', true);
17743			}
17744
17745			if (callback) {
17746				callback();
17747			}
17748		} // Static
17749		;
17750
17751		Tab._jQueryInterface = function _jQueryInterface(config) {
17752			return this.each(function () {
17753				var $this = $__default['default'](this);
17754				var data = $this.data(DATA_KEY$9);
17755
17756				if (!data) {
17757					data = new Tab(this);
17758					$this.data(DATA_KEY$9, data);
17759				}
17760
17761				if (typeof config === 'string') {
17762					if (typeof data[config] === 'undefined') {
17763						throw new TypeError("No method named \"" + config + "\"");
17764					}
17765
17766					data[config]();
17767				}
17768			});
17769		};
17770
17771		_createClass(Tab, null, [{
17772			key: "VERSION",
17773			get: function get() {
17774				return VERSION$9;
17775			}
17776		}]);
17777
17778		return Tab;
17779	}();
17780	/**
17781	 * ------------------------------------------------------------------------
17782	 * Data Api implementation
17783	 * ------------------------------------------------------------------------
17784	 */
17785
17786
17787	$__default['default'](document).on(EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$4, function (event) {
17788		event.preventDefault();
17789
17790		Tab._jQueryInterface.call($__default['default'](this), 'show');
17791	});
17792	/**
17793	 * ------------------------------------------------------------------------
17794	 * jQuery
17795	 * ------------------------------------------------------------------------
17796	 */
17797
17798	$__default['default'].fn[NAME$9] = Tab._jQueryInterface;
17799	$__default['default'].fn[NAME$9].Constructor = Tab;
17800
17801	$__default['default'].fn[NAME$9].noConflict = function () {
17802		$__default['default'].fn[NAME$9] = JQUERY_NO_CONFLICT$9;
17803		return Tab._jQueryInterface;
17804	};
17805
17806	/**
17807	 * ------------------------------------------------------------------------
17808	 * Constants
17809	 * ------------------------------------------------------------------------
17810	 */
17811
17812	var NAME$a = 'toast';
17813	var VERSION$a = '4.5.3';
17814	var DATA_KEY$a = 'bs.toast';
17815	var EVENT_KEY$a = "." + DATA_KEY$a;
17816	var JQUERY_NO_CONFLICT$a = $__default['default'].fn[NAME$a];
17817	var EVENT_CLICK_DISMISS$1 = "click.dismiss" + EVENT_KEY$a;
17818	var EVENT_HIDE$4 = "hide" + EVENT_KEY$a;
17819	var EVENT_HIDDEN$4 = "hidden" + EVENT_KEY$a;
17820	var EVENT_SHOW$4 = "show" + EVENT_KEY$a;
17821	var EVENT_SHOWN$4 = "shown" + EVENT_KEY$a;
17822	var CLASS_NAME_FADE$5 = 'fade';
17823	var CLASS_NAME_HIDE = 'hide';
17824	var CLASS_NAME_SHOW$7 = 'show';
17825	var CLASS_NAME_SHOWING = 'showing';
17826	var DefaultType$7 = {
17827		animation: 'boolean',
17828		autohide: 'boolean',
17829		delay: 'number'
17830	};
17831	var Default$7 = {
17832		animation: true,
17833		autohide: true,
17834		delay: 500
17835	};
17836	var SELECTOR_DATA_DISMISS$1 = '[data-dismiss="toast"]';
17837	/**
17838	 * ------------------------------------------------------------------------
17839	 * Class Definition
17840	 * ------------------------------------------------------------------------
17841	 */
17842
17843	var Toast = /*#__PURE__*/function () {
17844		function Toast(element, config) {
17845			this._element = element;
17846			this._config = this._getConfig(config);
17847			this._timeout = null;
17848
17849			this._setListeners();
17850		} // Getters
17851
17852
17853		var _proto = Toast.prototype;
17854
17855		// Public
17856		_proto.show = function show() {
17857			var _this = this;
17858
17859			var showEvent = $__default['default'].Event(EVENT_SHOW$4);
17860			$__default['default'](this._element).trigger(showEvent);
17861
17862			if (showEvent.isDefaultPrevented()) {
17863				return;
17864			}
17865
17866			this._clearTimeout();
17867
17868			if (this._config.animation) {
17869				this._element.classList.add(CLASS_NAME_FADE$5);
17870			}
17871
17872			var complete = function complete() {
17873				_this._element.classList.remove(CLASS_NAME_SHOWING);
17874
17875				_this._element.classList.add(CLASS_NAME_SHOW$7);
17876
17877				$__default['default'](_this._element).trigger(EVENT_SHOWN$4);
17878
17879				if (_this._config.autohide) {
17880					_this._timeout = setTimeout(function () {
17881						_this.hide();
17882					}, _this._config.delay);
17883				}
17884			};
17885
17886			this._element.classList.remove(CLASS_NAME_HIDE);
17887
17888			Util.reflow(this._element);
17889
17890			this._element.classList.add(CLASS_NAME_SHOWING);
17891
17892			if (this._config.animation) {
17893				var transitionDuration = Util.getTransitionDurationFromElement(this._element);
17894				$__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
17895			} else {
17896				complete();
17897			}
17898		};
17899
17900		_proto.hide = function hide() {
17901			if (!this._element.classList.contains(CLASS_NAME_SHOW$7)) {
17902				return;
17903			}
17904
17905			var hideEvent = $__default['default'].Event(EVENT_HIDE$4);
17906			$__default['default'](this._element).trigger(hideEvent);
17907
17908			if (hideEvent.isDefaultPrevented()) {
17909				return;
17910			}
17911
17912			this._close();
17913		};
17914
17915		_proto.dispose = function dispose() {
17916			this._clearTimeout();
17917
17918			if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
17919				this._element.classList.remove(CLASS_NAME_SHOW$7);
17920			}
17921
17922			$__default['default'](this._element).off(EVENT_CLICK_DISMISS$1);
17923			$__default['default'].removeData(this._element, DATA_KEY$a);
17924			this._element = null;
17925			this._config = null;
17926		} // Private
17927		;
17928
17929		_proto._getConfig = function _getConfig(config) {
17930			config = _extends({}, Default$7, $__default['default'](this._element).data(), typeof config === 'object' && config ? config : {});
17931			Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
17932			return config;
17933		};
17934
17935		_proto._setListeners = function _setListeners() {
17936			var _this2 = this;
17937
17938			$__default['default'](this._element).on(EVENT_CLICK_DISMISS$1, SELECTOR_DATA_DISMISS$1, function () {
17939				return _this2.hide();
17940			});
17941		};
17942
17943		_proto._close = function _close() {
17944			var _this3 = this;
17945
17946			var complete = function complete() {
17947				_this3._element.classList.add(CLASS_NAME_HIDE);
17948
17949				$__default['default'](_this3._element).trigger(EVENT_HIDDEN$4);
17950			};
17951
17952			this._element.classList.remove(CLASS_NAME_SHOW$7);
17953
17954			if (this._config.animation) {
17955				var transitionDuration = Util.getTransitionDurationFromElement(this._element);
17956				$__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
17957			} else {
17958				complete();
17959			}
17960		};
17961
17962		_proto._clearTimeout = function _clearTimeout() {
17963			clearTimeout(this._timeout);
17964			this._timeout = null;
17965		} // Static
17966		;
17967
17968		Toast._jQueryInterface = function _jQueryInterface(config) {
17969			return this.each(function () {
17970				var $element = $__default['default'](this);
17971				var data = $element.data(DATA_KEY$a);
17972
17973				var _config = typeof config === 'object' && config;
17974
17975				if (!data) {
17976					data = new Toast(this, _config);
17977					$element.data(DATA_KEY$a, data);
17978				}
17979
17980				if (typeof config === 'string') {
17981					if (typeof data[config] === 'undefined') {
17982						throw new TypeError("No method named \"" + config + "\"");
17983					}
17984
17985					data[config](this);
17986				}
17987			});
17988		};
17989
17990		_createClass(Toast, null, [{
17991			key: "VERSION",
17992			get: function get() {
17993				return VERSION$a;
17994			}
17995		}, {
17996			key: "DefaultType",
17997			get: function get() {
17998				return DefaultType$7;
17999			}
18000		}, {
18001			key: "Default",
18002			get: function get() {
18003				return Default$7;
18004			}
18005		}]);
18006
18007		return Toast;
18008	}();
18009	/**
18010	 * ------------------------------------------------------------------------
18011	 * jQuery
18012	 * ------------------------------------------------------------------------
18013	 */
18014
18015
18016	$__default['default'].fn[NAME$a] = Toast._jQueryInterface;
18017	$__default['default'].fn[NAME$a].Constructor = Toast;
18018
18019	$__default['default'].fn[NAME$a].noConflict = function () {
18020		$__default['default'].fn[NAME$a] = JQUERY_NO_CONFLICT$a;
18021		return Toast._jQueryInterface;
18022	};
18023
18024	exports.Alert = Alert;
18025	exports.Button = Button;
18026	exports.Carousel = Carousel;
18027	exports.Collapse = Collapse;
18028	exports.Dropdown = Dropdown;
18029	exports.Modal = Modal;
18030	exports.Popover = Popover;
18031	exports.Scrollspy = ScrollSpy;
18032	exports.Tab = Tab;
18033	exports.Toast = Toast;
18034	exports.Tooltip = Tooltip;
18035	exports.Util = Util;
18036
18037	Object.defineProperty(exports, '__esModule', { value: true });
18038
18039})));
18040//# sourceMappingURL=bootstrap.bundle.js.map
18041
18042/*!
18043 * iCheck v1.0.3, http://git.io/arlzeA
18044 * ===================================
18045 * Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization
18046 *
18047 * (c) 2013 Damir Sultanov, http://fronteed.com
18048 * MIT Licensed
18049 */
18050
18051(function($) {
18052
18053	// Cached vars
18054	var _iCheck = 'iCheck',
18055		_iCheckHelper = _iCheck + '-helper',
18056		_checkbox = 'checkbox',
18057		_radio = 'radio',
18058		_checked = 'checked',
18059		_unchecked = 'un' + _checked,
18060		_disabled = 'disabled',
18061		_determinate = 'determinate',
18062		_indeterminate = 'in' + _determinate,
18063		_update = 'update',
18064		_type = 'type',
18065		_click = 'click',
18066		_touch = 'touchbegin.i touchend.i',
18067		_add = 'addClass',
18068		_remove = 'removeClass',
18069		_callback = 'trigger',
18070		_label = 'label',
18071		_cursor = 'cursor',
18072		_mobile = /ip(hone|od|ad)|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
18073
18074	// Plugin init
18075	$.fn[_iCheck] = function(options, fire) {
18076
18077		// Walker
18078		var handle = 'input[type="' + _checkbox + '"], input[type="' + _radio + '"]',
18079			stack = $(),
18080			walker = function(object) {
18081				object.each(function() {
18082					var self = $(this);
18083
18084					if (self.is(handle)) {
18085						stack = stack.add(self);
18086					} else {
18087						stack = stack.add(self.find(handle));
18088					}
18089				});
18090			};
18091
18092		// Check if we should operate with some method
18093		if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {
18094
18095			// Normalize method's name
18096			options = options.toLowerCase();
18097
18098			// Find checkboxes and radio buttons
18099			walker(this);
18100
18101			return stack.each(function() {
18102				var self = $(this);
18103
18104				if (options == 'destroy') {
18105					tidy(self, 'ifDestroyed');
18106				} else {
18107					operate(self, true, options);
18108				}
18109
18110				// Fire method's callback
18111				if ($.isFunction(fire)) {
18112					fire();
18113				}
18114			});
18115
18116			// Customization
18117		} else if (typeof options == 'object' || !options) {
18118
18119			// Check if any options were passed
18120			var settings = $.extend({
18121					checkedClass: _checked,
18122					disabledClass: _disabled,
18123					indeterminateClass: _indeterminate,
18124					labelHover: true
18125				}, options),
18126
18127				selector = settings.handle,
18128				hoverClass = settings.hoverClass || 'hover',
18129				focusClass = settings.focusClass || 'focus',
18130				activeClass = settings.activeClass || 'active',
18131				labelHover = !!settings.labelHover,
18132				labelHoverClass = settings.labelHoverClass || 'hover',
18133
18134				// Setup clickable area
18135				area = ('' + settings.increaseArea).replace('%', '') | 0;
18136
18137			// Selector limit
18138			if (selector == _checkbox || selector == _radio) {
18139				handle = 'input[type="' + selector + '"]';
18140			}
18141
18142			// Clickable area limit
18143			if (area < -50) {
18144				area = -50;
18145			}
18146
18147			// Walk around the selector
18148			walker(this);
18149
18150			return stack.each(function() {
18151				var self = $(this);
18152
18153				// If already customized
18154				tidy(self);
18155
18156				var node = this,
18157					id = node.id,
18158
18159					// Layer styles
18160					offset = -area + '%',
18161					size = 100 + (area * 2) + '%',
18162					layer = {
18163						position: 'absolute',
18164						top: offset,
18165						left: offset,
18166						display: 'block',
18167						width: size,
18168						height: size,
18169						margin: 0,
18170						padding: 0,
18171						background: '#fff',
18172						border: 0,
18173						opacity: 0
18174					},
18175
18176					// Choose how to hide input
18177					hide = _mobile ? {
18178						position: 'absolute',
18179						visibility: 'hidden'
18180					} : area ? layer : {
18181						position: 'absolute',
18182						opacity: 0
18183					},
18184
18185					// Get proper class
vendor: 7,609 bytes, lines 18186-18486
18186					className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,
18187
18188					// Find assigned labels
18189					label = $(_label + '[for="' + id + '"]').add(self.closest(_label)),
18190
18191					// Check ARIA option
18192					aria = !!settings.aria,
18193
18194					// Set ARIA placeholder
18195					ariaID = _iCheck + '-' + Math.random().toString(36).substr(2,6),
18196
18197					// Parent & helper
18198					parent = '<div class="' + className + '" ' + (aria ? 'role="' + node[_type] + '" ' : ''),
18199					helper;
18200
18201				// Set ARIA "labelledby"
18202				if (aria) {
18203					label.each(function() {
18204						parent += 'aria-labelledby="';
18205
18206						if (this.id) {
18207							parent += this.id;
18208						} else {
18209							this.id = ariaID;
18210							parent += ariaID;
18211						}
18212
18213						parent += '"';
18214					});
18215				}
18216
18217				// Wrap input
18218				parent = self.wrap(parent + '/>')[_callback]('ifCreated').parent().append(settings.insert);
18219
18220				// Layer addition
18221				helper = $('<ins class="' + _iCheckHelper + '"/>').css(layer).appendTo(parent);
18222
18223				// Finalize customization
18224				self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);
18225				!!settings.inheritClass && parent[_add](node.className || '');
18226				!!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);
18227				parent.css('position') == 'static' && parent.css('position', 'relative');
18228				operate(self, true, _update);
18229
18230				// Label events
18231				if (label.length) {
18232					label.on(_click + '.i mouseover.i mouseout.i ' + _touch, function(event) {
18233						var type = event[_type],
18234							item = $(this);
18235
18236						// Do nothing if input is disabled
18237						if (!node[_disabled]) {
18238
18239							// Click
18240							if (type == _click) {
18241								if ($(event.target).is('a')) {
18242									return;
18243								}
18244								operate(self, false, true);
18245
18246								// Hover state
18247							} else if (labelHover) {
18248
18249								// mouseout|touchend
18250								if (/ut|nd/.test(type)) {
18251									parent[_remove](hoverClass);
18252									item[_remove](labelHoverClass);
18253								} else {
18254									parent[_add](hoverClass);
18255									item[_add](labelHoverClass);
18256								}
18257							}
18258
18259							if (_mobile) {
18260								event.stopPropagation();
18261							} else {
18262								return false;
18263							}
18264						}
18265					});
18266				}
18267
18268				// Input events
18269				self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {
18270					var type = event[_type],
18271						key = event.keyCode;
18272
18273					// Click
18274					if (type == _click) {
18275						return false;
18276
18277						// Keydown
18278					} else if (type == 'keydown' && key == 32) {
18279						if (!(node[_type] == _radio && node[_checked])) {
18280							if (node[_checked]) {
18281								off(self, _checked);
18282							} else {
18283								on(self, _checked);
18284							}
18285						}
18286
18287						return false;
18288
18289						// Keyup
18290					} else if (type == 'keyup' && node[_type] == _radio) {
18291						!node[_checked] && on(self, _checked);
18292
18293						// Focus/blur
18294					} else if (/us|ur/.test(type)) {
18295						parent[type == 'blur' ? _remove : _add](focusClass);
18296					}
18297				});
18298
18299				// Helper events
18300				helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {
18301					var type = event[_type],
18302
18303						// mousedown|mouseup
18304						toggle = /wn|up/.test(type) ? activeClass : hoverClass;
18305
18306					// Do nothing if input is disabled
18307					if (!node[_disabled]) {
18308
18309						// Click
18310						if (type == _click) {
18311							operate(self, false, true);
18312
18313							// Active and hover states
18314						} else {
18315
18316							// State is on
18317							if (/wn|er|in/.test(type)) {
18318
18319								// mousedown|mouseover|touchbegin
18320								parent[_add](toggle);
18321
18322								// State is off
18323							} else {
18324								parent[_remove](toggle + ' ' + activeClass);
18325							}
18326
18327							// Label hover
18328							if (label.length && labelHover && toggle == hoverClass) {
18329
18330								// mouseout|touchend
18331								label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);
18332							}
18333						}
18334
18335						if (_mobile) {
18336							event.stopPropagation();
18337						} else {
18338							return false;
18339						}
18340					}
18341				});
18342			});
18343		} else {
18344			return this;
18345		}
18346	};
18347
18348	// Do something with inputs
18349	function operate(input, direct, method) {
18350		var node = input[0],
18351			state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,
18352			active = method == _update ? {
18353				checked: node[_checked],
18354				disabled: node[_disabled],
18355				indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'
18356			} : node[state];
18357
18358		// Check, disable or indeterminate
18359		if (/^(ch|di|in)/.test(method) && !active) {
18360			on(input, state);
18361
18362			// Uncheck, enable or determinate
18363		} else if (/^(un|en|de)/.test(method) && active) {
18364			off(input, state);
18365
18366			// Update
18367		} else if (method == _update) {
18368
18369			// Handle states
18370			for (var each in active) {
18371				if (active[each]) {
18372					on(input, each, true);
18373				} else {
18374					off(input, each, true);
18375				}
18376			}
18377
18378		} else if (!direct || method == 'toggle') {
18379
18380			// Helper or label was clicked
18381			if (!direct) {
18382				input[_callback]('ifClicked');
18383			}
18384
18385			// Toggle checked state
18386			if (active) {
18387				if (node[_type] !== _radio) {
18388					off(input, state);
18389				}
18390			} else {
18391				on(input, state);
18392			}
18393		}
18394	}
18395
18396	// Add checked, disabled or indeterminate state
18397	function on(input, state, keep) {
18398		var node = input[0],
18399			parent = input.parent(),
18400			checked = state == _checked,
18401			indeterminate = state == _indeterminate,
18402			disabled = state == _disabled,
18403			callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
18404			regular = option(input, callback + capitalize(node[_type])),
18405			specific = option(input, state + capitalize(node[_type]));
18406
18407		// Prevent unnecessary actions
18408		if (node[state] !== true) {
18409
18410			// Toggle assigned radio buttons
18411			if (!keep && state == _checked && node[_type] == _radio && node.name) {
18412				var form = input.closest('form'),
18413					inputs = 'input[name="' + node.name + '"]';
18414
18415				inputs = form.length ? form.find(inputs) : $(inputs);
18416
18417				inputs.each(function() {
18418					if (this !== node && $(this).data(_iCheck)) {
18419						off($(this), state);
18420					}
18421				});
18422			}
18423
18424			// Indeterminate state
18425			if (indeterminate) {
18426
18427				// Add indeterminate state
18428				node[state] = true;
18429
18430				// Remove checked state
18431				if (node[_checked]) {
18432					off(input, _checked, 'force');
18433				}
18434
18435				// Checked or disabled state
18436			} else {
18437
18438				// Add checked or disabled state
18439				if (!keep) {
18440					node[state] = true;
18441				}
18442
18443				// Remove indeterminate state
18444				if (checked && node[_indeterminate]) {
18445					off(input, _indeterminate, false);
18446				}
18447			}
18448
18449			// Trigger callbacks
18450			callbacks(input, checked, state, keep);
18451		}
18452
18453		// Add proper cursor
18454		if (node[_disabled] && !!option(input, _cursor, true)) {
18455			parent.find('.' + _iCheckHelper).css(_cursor, 'default');
18456		}
18457
18458		// Add state class
18459		parent[_add](specific || option(input, state) || '');
18460
18461		// Set ARIA attribute
18462		if (!!parent.attr('role') && !indeterminate) {
18463			parent.attr('aria-' + (disabled ? _disabled : _checked), 'true');
18464		}
18465
18466		// Remove regular state class
18467		parent[_remove](regular || option(input, callback) || '');
18468	}
18469
18470	// Remove checked, disabled or indeterminate state
18471	function off(input, state, keep) {
18472		var node = input[0],
18473			parent = input.parent(),
18474			checked = state == _checked,
18475			indeterminate = state == _indeterminate,
18476			disabled = state == _disabled,
18477			callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
18478			regular = option(input, callback + capitalize(node[_type])),
18479			specific = option(input, state + capitalize(node[_type]));
18480
18481		// Prevent unnecessary actions
18482		if (node[state] !== false) {
18483
18484			// Toggle state
18485			if (indeterminate || !keep || keep == 'force') {
18486				node[state] = false;
18487			}
18488
18489			// Trigger callbacks
18490			callbacks(input, checked, callback, keep);
18491		}
18492
18493		// Add proper cursor
18494		if (!node[_disabled] && !!option(input, _cursor, true)) {
18495			parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');
18496		}
18497
18498		// Remove state class
18499		parent[_remove](specific || option(input, state) || '');
18500
18501		// Set ARIA attribute
18502		if (!!parent.attr('role') && !indeterminate) {
18503			parent.attr('aria-' + (disabled ? _disabled : _checked), 'false');
18504		}
18505
18506		// Add regular state class
18507		parent[_add](regular || option(input, callback) || '');
18508	}
18509
18510	// Remove all traces
18511	function tidy(input, callback) {
18512		if (input.data(_iCheck)) {
18513
18514			// Remove everything except input
18515			input.parent().html(input.attr('style', input.data(_iCheck).s || ''));
18516
18517			// Callback
18518			if (callback) {
18519				input[_callback](callback);
18520			}
18521
18522			// Unbind events
18523			input.off('.i').unwrap();
18524			$(_label + '[for="' + input[0].id + '"]').add(input.closest(_label)).off('.i');
18525		}
18526	}
18527
18528	// Get some option
18529	function option(input, state, regular) {
18530		if (input.data(_iCheck)) {
18531			return input.data(_iCheck).o[state + (regular ? '' : 'Class')];
18532		}
18533	}
18534
18535	// Capitalize some string
18536	function capitalize(string) {
18537		return string.charAt(0).toUpperCase() + string.slice(1);
18538	}
18539
18540	// Executable handlers
18541	function callbacks(input, checked, callback, keep) {
18542		if (!keep) {
18543			if (checked) {
18544				input[_callback]('ifToggled');
18545			}
18546
18547			input[_callback]('change')[_callback]('ifChanged')[_callback]('if' + capitalize(callback));
18548		}
18549	}
18550})(window.jQuery || window.Zepto);
18551
18552/**
18553 * WHMCS core JS library reference
18554 *
18555 * @copyright Copyright (c) WHMCS Limited 2005-2017
18556 * @license http://www.whmcs.com/license/ WHMCS Eula
18557 */
18558
18559(function (window, factory) {
18560	if (typeof window.WHMCS !== 'object') {
18561		window.WHMCS = factory;
18562	}
18563}(
18564	window,
18565	{
18566		hasModule: function (name) {
18567			return (typeof WHMCS[name] !== 'undefined'
18568				&& Object.getOwnPropertyNames(WHMCS[name]).length > 0);
18569		},
18570		loadModule: function (name, module) {
18571			if (this.hasModule(name)) {
18572				return;
18573			}
18574
18575			WHMCS[name] = {};
18576			if (typeof module === 'function') {
18577				(module).apply(WHMCS[name]);
18578			} else {
18579				for (var key in module) {
18580					if (module.hasOwnProperty(key)) {
18581						WHMCS[name][key] = {};
18582						(module[key]).apply(WHMCS[name][key]);
18583					}
18584				}
18585			}
18586		}
18587	}
18588));
18589
18590jQuery(document).ready(function() {
18591	jQuery(document).on('click', '.disable-on-click', function () {
18592		jQuery(this).addClass('disabled');
18593
18594		if (jQuery(this).hasClass('spinner-on-click')) {
18595			var icon = $(this).find('i.fas,i.far,i.fal,i.fab');
18596
18597			jQuery(icon)
18598				.removeAttr('class')
18599				.addClass('fas fa-spinner fa-spin');
18600		}
18601	})
18602		.on('click', '#openTicketSubmit.disabled', function () {
18603			return false;
18604		});
18605	window.flagForScrollBug = true;
18606});
18607
18608function scrollToGatewayInputError() {
18609	var displayError = jQuery('.gateway-errors,.assisted-cc-input-feedback').first(),
18610		frm = displayError.closest('form');
18611	if (!frm) {
18612		frm = jQuery('form').first();
18613	}
18614	frm.find('button[type="submit"],input[type="submit"]')
18615		.prop('disabled', false)
18616		.removeClass('disabled')
18617		.find('i.fas,i.far,i.fal,i.fab')
18618		.removeAttr('class')
18619		.addClass('fas fa-arrow-circle-right')
18620		.find('span').toggle();
18621
18622	$('.pay-text').show()
18623	$('.click-text').hide()
18624
18625	if (displayError.length && window.test === true) {
18626		window.flagForScrollBug = false;
18627		if (elementOutOfViewPort(displayError[0])) {
18628			jQuery('html, body').animate(
18629				{
18630					scrollTop: displayError.offset().top - 50
18631				},
18632				500
18633			);
18634		}
18635	}
18636}
18637
18638function elementOutOfViewPort(element) {
18639	// Get element's bounding
18640	var bounding = element.getBoundingClientRect();
18641	// Check if it's out of the viewport on each side
18642	var out = {};
18643	out.top = bounding.top < 0;
18644	out.left = bounding.left < 0;
18645	out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
18646	out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
18647	out.any = out.top || out.left || out.bottom || out.right;
18648
18649	return out.any;
18650};
18651
18652/**
18653 * WHMCS authentication module
18654 *
18655 * @copyright Copyright (c) WHMCS Limited 2005-2017
18656 * @license http://www.whmcs.com/license/ WHMCS Eula
18657 */
18658
18659(function(module) {
18660	if (!WHMCS.hasModule('authn')) {
18661		WHMCS.loadModule('authn', module);
18662	}
18663})({
18664	provider: function () {
18665		var callbackFired = false;
18666
18667		/**
18668		 * @return {jQuery}
18669		 */
18670		this.feedbackContainer = function () {
18671			return jQuery(".providerLinkingFeedback");
18672		};
18673
18674		/**
18675		 * @returns {jQuery}
18676		 */
18677		this.btnContainer = function () {
18678			return jQuery(".providerPreLinking");
18679		};
18680
18681		this.feedbackMessage = function (context) {
18682			if (typeof context === 'undefined') {
18683				context = 'complete_sign_in';
18684			}
18685			var msgContainer = jQuery('p.providerLinkingMsg-preLink-' + context);
18686			if (msgContainer.length) {
18687				return msgContainer.first().html();
18688			}
18689
18690			return '';
18691		};
18692
18693		this.showProgressMessage = function(callback) {
18694			this.feedbackContainer().fadeIn('fast', function () {
18695				if (typeof callback === 'function' && !callbackFired) {
18696					callbackFired = true;
18697					callback();
18698				}
18699			});
18700		};
18701
18702		this.preLinkInit = function (callback) {
18703			var icon = '<i class="fas fa-fw fa-spinner fa-spin"></i> ';
18704
18705			this.feedbackContainer()
18706				.removeClass('alert-danger alert-success')
18707				.addClass('alert alert-info')
18708				.html(icon + this.feedbackMessage())
18709				.hide();
18710
18711			var btnContainer = this.btnContainer();
18712			if (btnContainer.length) {
18713				if (btnContainer.data('hideOnPrelink')) {
18714					var self = this;
18715					btnContainer.fadeOut('false', function ()
18716					{
18717						self.showProgressMessage(callback)
18718					});
18719				} else if (btnContainer.data('disableOnPrelink')) {
18720					btnContainer.find('.btn').addClass('disabled');
18721					this.showProgressMessage(callback);
18722				} else {
18723					this.showProgressMessage(callback);
18724				}
18725			} else {
18726				this.showProgressMessage(callback);
18727			}
18728		};
18729
18730		this.displayError = function (provider, errorCondition, providerErrorText){
18731			jQuery('#providerLinkingMessages .provider-name').html(provider);
18732
18733			var feedbackMsg = this.feedbackMessage('connect_error');
18734			if (errorCondition) {
18735				var errorMsg = this.feedbackMessage(errorCondition);
18736				if (errorMsg) {
18737					feedbackMsg = errorMsg
18738				}
18739			}
18740
18741			if (providerErrorText && $('.btn-logged-in-admin').length > 0) {
18742				feedbackMsg += ' Error: ' + providerErrorText;
18743			}
18744
18745			this.feedbackContainer().removeClass('alert-info alert-success')
18746				.addClass('alert alert-danger')
18747				.html(feedbackMsg).slideDown();
18748		};
18749
18750		this.displaySuccess = function (data, context, provider) {
18751			var icon = provider.icon;
18752			var htmlTarget = context.htmlTarget;
18753			var targetLogin = context.targetLogin;
18754			var targetRegister = context.targetRegister;
18755			var displayName = provider.name;
18756			var feedbackMsg = '';
18757
18758			switch (data.result) {
18759				case "logged_in":
18760				case "2fa_needed":
18761					feedbackMsg = this.feedbackMessage('2fa_needed');
18762					this.feedbackContainer().removeClass('alert-danger alert-warning alert-success')
18763						.addClass('alert alert-info')
18764						.html(feedbackMsg);
18765
18766					window.location = data.redirect_url
18767						? decodeURIComponent(data.redirect_url)
18768						: decodeURIComponent(context.redirectUrl);
18769
18770					break;
18771
18772				case "linking_complete":
18773					var accountInfo = '';
18774					if (data.remote_account.email) {
18775						accountInfo = data.remote_account.email;
18776					} else {
18777						accountInfo = data.remote_account.firstname + " " + data.remote_account.lastname;
18778					}
18779
18780					accountInfo = accountInfo.trim();
18781
18782					feedbackMsg = this.feedbackMessage('linking_complete').trim().replace(':displayName', displayName);
18783					if (accountInfo) {
18784						feedbackMsg = feedbackMsg.replace(/\.$/, ' (' + accountInfo + ').');
18785					}
18786
18787					this.feedbackContainer().removeClass('alert-danger alert-warning alert-info')
18788						.addClass('alert alert-success')
18789						.html(icon + feedbackMsg);
18790					break;
18791
18792				case "login_to_link":
18793					if (htmlTarget === targetLogin) {
18794						feedbackMsg = this.feedbackMessage('login_to_link-signin-required');
18795						this.feedbackContainer().removeClass('alert-danger alert-success alert-info')
18796							.addClass('alert alert-warning')
18797							.html(icon + feedbackMsg);
18798					} else {
18799						var emailField = jQuery("input[name=email]");
18800						var firstNameField = jQuery("input[name=firstname]");
18801						var lastNameField = jQuery("input[name=lastname]");
18802
18803						if (emailField.val() === "") {
18804							emailField.val(data.remote_account.email);
18805						}
18806
18807						if (firstNameField.val() === "") {
18808							firstNameField.val(data.remote_account.firstname);
18809						}
18810
18811						if (lastNameField.val() === "") {
18812							lastNameField.val(data.remote_account.lastname);
18813						}
18814
18815						if (htmlTarget === targetRegister) {
18816							if (typeof WHMCS.client.registration === 'object') {
18817								WHMCS.client.registration.prefillPassword();
18818							}
18819							feedbackMsg = this.feedbackMessage('login_to_link-registration-required');
18820							this.feedbackContainer().fadeOut('slow', function () {
18821								$(this).removeClass('alert-danger alert-success alert-info')
18822									.addClass('alert alert-warning')
18823									.html(icon + feedbackMsg).fadeIn('fast');
18824							});
18825
18826						} else {
18827							// this is checkout
18828							if (typeof WHMCS.client.registration === 'object') {
18829								WHMCS.client.registration.prefillPassword();
18830							}
18831
18832							var self = this;
18833							this.feedbackContainer().each(function (i, el) {
18834								var container = $(el);
18835								var linkContext = container.siblings('div .providerPreLinking').data('linkContext');
18836
18837								container.fadeOut('slow', function () {
18838									if (linkContext === 'checkout-new') {
18839										feedbackMsg = self.feedbackMessage('checkout-new');
18840									} else {
18841										feedbackMsg = self.feedbackMessage('login_to_link-signin-required');
18842									}
18843									container.removeClass('alert-danger alert-success alert-info')
18844										.addClass('alert alert-warning')
18845										.html(icon + feedbackMsg).fadeIn('fast');
18846								});
18847							});
18848						}
18849					}
18850
18851					break;
18852
18853				case "other_user_exists":
18854					feedbackMsg = this.feedbackMessage('other_user_exists');
18855					this.feedbackContainer().removeClass('alert-info alert-success')
18856						.addClass('alert alert-danger')
18857						.html(icon + feedbackMsg).slideDown();
18858					break;
18859
18860				case "already_linked":
18861					feedbackMsg = this.feedbackMessage('already_linked');
18862					this.feedbackContainer().removeClass('alert-info alert-success')
18863						.addClass('alert alert-danger')
18864						.html(icon + feedbackMsg).slideDown();
18865					break;
18866
18867				default:
18868					feedbackMsg = this.feedbackMessage('default');
18869					this.feedbackContainer().removeClass('alert-info alert-success')
18870						.addClass('alert alert-danger')
18871						.html(icon + feedbackMsg).slideDown();
18872					break;
18873			}
18874		};
18875
18876		this.signIn = function (config, context, provider, providerDone, providerError) {
18877			jQuery.ajax(config).done(function(data) {
18878				providerDone();
18879				WHMCS.authn.provider.displaySuccess(data, context, provider);
18880				var table = jQuery('#tableLinkedAccounts');
18881				if (table.length) {
18882					WHMCS.ui.dataTable.getTableById('tableLinkedAccounts').ajax.reload();
18883				}
18884			}).error(function() {
18885				providerError();
18886				WHMCS.authn.provider.displayError();
18887			});
18888		};
18889
18890		return this;
18891	}});
18892
18893/**
18894 * WHMCS client module
18895 *
18896 * @copyright Copyright (c) WHMCS Limited 2005-2017
18897 * @license http://www.whmcs.com/license/ WHMCS Eula
18898 */
18899(function(module) {
18900	if (!WHMCS.hasModule('client')) {
18901		WHMCS.loadModule('client', module);
18902	}
18903})({
18904	registration: function () {
18905		this.prefillPassword = function (params) {
18906			params = params || {};
18907			if (typeof params.hideContainer === 'undefined') {
18908				var id = (jQuery('#inputSecurityQId').attr('id')) ? '#containerPassword' : '#containerNewUserSecurity';
18909				params.hideContainer = jQuery(id);
18910				params.hideInputs = true;
18911			} else if (typeof params.hideContainer === 'string' && params.hideContainer.length) {
18912				params.hideContainer = jQuery(params.hideContainer);
18913			}
18914
18915			if (typeof params.form === 'undefined') {
18916				params.form = {
18917					password: [
18918						{id: 'inputNewPassword1'},
18919						{id: 'inputNewPassword2'}
18920					]
18921				};
18922			}
18923
18924			var prefillFunc = function () {
18925				var $randomPasswd = WHMCS.utils.simpleRNG();
18926				for (var i = 0, len = params.form.password.length; i < len; i++) {
18927					jQuery('#' + params.form.password[i].id)
18928						.val($randomPasswd).trigger('keyup');
18929				}
18930			};
18931
18932			if (params.hideInputs) {
18933				params.hideContainer.slideUp('fast', prefillFunc);
18934			} else {
18935				prefillFunc();
18936			}
18937		};
18938
18939		return this;
18940	}});
18941
18942/**
18943 * WHMCS HTTP module
18944 *
18945 * @copyright Copyright (c) WHMCS Limited 2005-2018
18946 * @license http://www.whmcs.com/license/ WHMCS Eula
18947 */
18948(function(module) {
18949	if (!WHMCS.hasModule('http')) {
18950		WHMCS.loadModule('http', module);
18951	}
18952})({
18953	jqClient: function () {
18954		_getSettings = function (url, data, success, dataType)
18955		{
18956			if (typeof url === 'object') {
18957				/*
18958                Settings may be the only argument
18959             */
18960				return url;
18961			}
18962
18963			if (typeof data === 'function') {
18964				/*
18965                If 'data' is omitted, 'success' will come in its place
18966             */
18967				success = data;
18968				data = null;
18969			}
18970
18971			return {
18972				url: url,
18973				data: data,
18974				success: success,
18975				dataType: dataType
18976			};
18977		};
18978
18979		/**
18980		 * @param url
18981		 * @param data
18982		 * @param success
18983		 * @param dataType
18984		 * @returns {*}
18985		 */
18986		this.get = function (url, data, success, dataType)
18987		{
18988			return WHMCS.http.client.request(
18989				jQuery.extend(
18990					_getSettings(url, data, success, dataType),
18991					{
18992						type: 'GET'
18993					}
18994				)
18995			);
18996		};
18997
18998		/**
18999		 * @param url
19000		 * @param data
19001		 * @param success
19002		 * @param dataType
19003		 * @returns {*}
19004		 */
19005		this.post = function (url, data, success, dataType)
19006		{
19007			return WHMCS.http.client.request(
19008				jQuery.extend(
19009					_getSettings(url, data, success, dataType),
19010					{
19011						type: 'POST'
19012					}
19013				)
19014			);
19015		};
19016
19017		/**
19018		 * @param options
19019		 * @returns {*}
19020		 */
19021		this.jsonGet = function (options) {
19022			options = options || {};
19023			this.get(options.url, options.data, function(response) {
19024				if (response.warning) {
19025					console.log('[WHMCS] Warning: ' + response.warning);
19026					if (typeof options.warning === 'function') {
19027						options.warning(response.warning);
19028					}
19029				} else if (response.error) {
19030					console.log('[WHMCS] Error: ' + response.error);
19031					if (typeof options.error === 'function') {
19032						options.error(response.error);
19033					}
19034				} else {
19035					if (typeof options.success === 'function') {
19036						options.success(response);
19037					}
19038				}
19039			}, 'json').error(function(xhr, errorMsg){
19040				console.log('[WHMCS] Error: ' + errorMsg);
19041				if (typeof options.fail === 'function') {
19042					options.fail(errorMsg);
19043				}
19044			}).always(function() {
19045				if (typeof options.always === 'function') {
19046					options.always();
19047				}
19048			});
19049		};
19050
19051		/**
19052		 * @param options
19053		 * @returns {*}
19054		 */
19055		this.jsonPost = function (options) {
19056			options = options || {};
19057			this.post(options.url, options.data, function(response) {
19058				if (response.warning) {
19059					console.log('[WHMCS] Warning: ' + response.warning);
19060					if (typeof options.warning === 'function') {
19061						options.warning(response.warning + ': Please contact our support team');
19062					}
19063				} else if (response.error) {
19064					console.log('[WHMCS] Error: ' + response.error);
19065					if (typeof options.error === 'function') {
19066						options.error(response.error);
19067					}
19068				} else {
19069					if (typeof options.success === 'function') {
19070						options.success(response);
19071					}
19072				}
19073			}, 'json').fail(function(xhr, errorMsg){
19074				console.log('[WHMCS] Fail: ' + errorMsg);
19075				if (typeof options.fail === 'function') {
19076					options.fail(errorMsg + xhr);
19077				}
19078			}).always(function() {
19079				if (typeof options.always === 'function') {
19080					options.always();
19081				}
19082			});
19083		};
19084
19085		return this;
19086	},
19087
19088	client: function () {
19089		var methods = ['get', 'post', 'put', 'delete'];
19090		var client = this;
19091
19092		_beforeRequest = function (settings)
19093		{
19094			/*
19095            Enforcing dataType was found to break many invocations expecting HTML back.
19096            If/when those are refactored, this may be uncommented to enforce a safer
19097            data transit.
19098         */
19099			/*if (typeof settings.dataType === 'undefined') {
19100            settings.dataType = 'json';
19101        }*/
19102
19103			if (typeof settings.type === 'undefined') {
19104				// default request type is GET
19105				settings.type = 'GET';
19106			}
19107
19108			/*
19109            Add other preprocessing here if required
19110         */
19111
19112			return settings;
19113		};
19114
19115		this.request = function (settings)
19116		{
19117			settings = _beforeRequest(settings || {});
19118			return jQuery.ajax(settings);
19119		};
19120
19121		/*
19122        Create shortcut methods for methods[] array above
19123     */
19124		jQuery.each(methods, function(index, method) {
19125			client[method] = (function(method, client) {
19126				return function (settings)
19127				{
19128					settings = settings || {};
19129
19130					settings.type = method.toUpperCase();
19131
19132					return client.request(settings);
19133				}
19134			})(method, client);
19135		});
19136
19137		return this;
19138	}
19139
19140});
19141
19142/**
19143 * WHMCS UI module
19144 *
19145 * @copyright Copyright (c) WHMCS Limited 2005-2017
19146 * @license http://www.whmcs.com/license/ WHMCS Eula
19147 */
19148(function(module) {
19149	if (!WHMCS.hasModule('ui')) {
19150		WHMCS.loadModule('ui', module);
19151	}
19152})({
19153	/**
19154	 * Confirmation PopUp
19155	 */
19156	confirmation: function () {
19157
19158		/**
19159		 * @type {Array} Registered confirmation root selectors
19160		 */
19161		var toggles = [];
19162
19163		/**
19164		 * Register/Re-Register all confirmation elements with jQuery
19165		 * By default all elements of data toggle "confirmation" will be registered
19166		 *
19167		 * @param {(string|undefined)} rootSelector
19168		 * @return {Array} array of registered toggles
19169		 */
19170		this.register = function (rootSelector) {
19171			if (typeof rootSelector === 'undefined') {
19172				rootSelector = '[data-toggle=confirmation]';
19173			}
19174			if (toggles.indexOf(rootSelector) < 0) {
19175				toggles.push(rootSelector);
19176			}
19177
19178			jQuery(rootSelector).confirmation({
19179				rootSelector: rootSelector
19180			});
19181
19182			return toggles;
19183		};
19184
19185		return this;
19186	},
19187
19188	/**
19189	 * Data Driven Table
19190	 */
19191	dataTable: function () {
19192
19193		/**
19194		 * @type {{}}
19195		 */
19196		this.tables = {};
19197
19198		/**
19199		 * Register all tables on page with the class "data-driven"
19200		 */
19201		this.register = function () {
19202			var self = this;
19203			jQuery('table.data-driven').each(function (i, table) {
19204				self.getTableById(table.id, undefined);
19205			});
19206		};
19207
19208		/**
19209		 * Get a table by id; create table object on fly as necessary
19210		 *
19211		 * @param {string} id
19212		 * @param {({}|undefined)} options
19213		 * @returns {DataTable}
19214		 */
19215		this.getTableById = function (id, options) {
19216			var self = this;
19217			var el = jQuery('#' + id);
19218			if (typeof self.tables[id] === 'undefined') {
19219				if (typeof options === 'undefined') {
19220					options = {
19221						dom: '<"listtable"ift>pl',
19222						paging: false,
19223						lengthChange: false,
19224						searching: false,
19225						ordering: true,
19226						info: false,
19227						autoWidth: true,
19228						columns: [],
19229						lengthMenu: [10, 25, 50, 100, 500, 1000],
19230						language: {
19231							emptyTable: (el.data('langEmptyTable')) ? el.data('langEmptyTable') : "No records foun
19231d"
19232						}
19233					};
19234				}
19235				jQuery.each(el.data(), function (key, value) {
19236					if (typeof value === 'undefined') {
19237						return;
19238					}
19239					if (key === 'ajaxUrl') {
19240						options.ajax = {
19241							url: value
19242						};
19243						return;
19244					}
19245					if (key === 'lengthChange') {
19246						options.lengthChange = value;
19247						return;
19248					}
19249					if (key === 'pageLength') {
19250						options.pageLength = value;
19251						return;
19252					}
19253					if (key === 'langEmptyTable') {
19254						if (typeof options.language === "undefined") {
19255							options.language = {};
19256						}
19257						options.language.emptyTable = value;
19258						return
19259					}
19260					if (key === 'langZeroRecords') {
19261						if (typeof options.language === "undefined") {
19262							options.language = {};
19263						}
19264						options.language.zeroRecords = value;
19265						return
19266					}
19267					options.key = value;
19268				});
19269				jQuery.each(el.find('th'), function() {
19270					if (typeof options.columns === "undefined") {
19271						options.columns = [];
19272					}
19273					options.columns.push({data:jQuery(this).data('name')});
19274				});
19275				self.tables[id] = self.initTable(el, options);
19276			} else if (typeof options !== 'undefined') {
19277				var oldTable = self.tables[id];
19278				var initOpts = oldTable.init();
19279				var newOpts = jQuery.extend( initOpts, options);
19280				oldTable.destroy();
19281				self.tables[id] = self.initTable(el, newOpts);
19282			}
19283
19284			return self.tables[id];
19285		};
19286
19287		this.initTable = function (el, options) {
19288			var table = el.DataTable(options);
19289			var self = this;
19290			if (el.data('on-draw')) {
19291				table.on('draw.dt', function (e, settings) {
19292					var namedCallback = el.data('on-draw');
19293					if (typeof window[namedCallback] === 'function') {
19294						window[namedCallback](e, settings);
19295					}
19296				});
19297			} else if (el.data('on-draw-rebind-confirmation')) {
19298				table.on('draw.dt', function (e) {
19299					self.rebindConfirmation(e);
19300				});
19301			}
19302
19303			return table;
19304		};
19305
19306		this.rebindConfirmation = function (e) {
19307			var self = this;
19308			var tableId = e.target.id;
19309			var toggles = WHMCS.ui.confirmation.register();
19310			for(var i = 0, len = toggles.length; i < len; i++ ) {
19311				jQuery(toggles[i]).on(
19312					'confirmed.bs.confirmation',
19313					function (e)
19314					{
19315						e.preventDefault();
19316						WHMCS.http.jqClient.post(
19317							jQuery(e.target).data('target-url'),
19318							{
19319								'token': csrfToken
19320							}
19321						).done(function (data)
19322						{
19323							if (data.status === 'success' || data.status === 'okay') {
19324								self.getTableById(tableId, undefined).ajax.reload();
19325							}
19326						});
19327
19328					}
19329				);
19330			}
19331		};
19332
19333		return this;
19334	},
19335
19336	clipboard: function() {
19337		this.copy = function(e) {
19338			e.preventDefault();
19339
19340			var trigger = $(e.currentTarget);
19341			var contentElement = $(trigger).data('clipboard-target');
19342			var container = $(contentElement).parent();
19343
19344			try {
19345				var tempElement = $('<textarea>')
19346					.css('position', 'fixed')
19347					.css('opacity', '0')
19348					.css('width', '1px')
19349					.css('height', '1px')
19350					.val($(contentElement).val());
19351
19352				container.append(tempElement);
19353				tempElement.focus().select();
19354				document.execCommand('copy');
19355			} finally {
19356				tempElement.remove();
19357			}
19358
19359			trigger.tooltip({
19360				trigger: 'click',
19361				placement: 'bottom'
19362			});
19363			WHMCS.ui.toolTip.setTip(trigger, 'Copied!');
19364			WHMCS.ui.toolTip.hideTip(trigger);
19365		};
19366
19367		return this;
19368	},
19369
19370	/**
19371	 * ToolTip and Clipboard behaviors
19372	 */
19373	toolTip: function () {
19374		this.setTip = function (btn, message) {
19375			var tip = btn.data('bs.tooltip');
19376			if (tip.hoverState !== 'in') {
19377				tip.hoverState = 'in';
19378			}
19379			btn.attr('data-original-title', message);
19380			tip.show();
19381
19382			return tip;
19383		};
19384
19385		this.hideTip = function (btn, timeout) {
19386			if (!timeout) {
19387				timeout = 2000;
19388			}
19389			return setTimeout(function() {
19390				btn.data('bs.tooltip').hide()
19391			}, timeout);
19392		}
19393	},
19394
19395	jsonForm: function() {
19396		this.managedElements = 'input,textarea,select';
19397
19398		this.initFields = function (form) {
19399			var self = this;
19400			$(form).find(self.managedElements).each(function () {
19401				var field = this;
19402
19403				$(field).on('keypress change', function () {
19404					if (self.fieldHasError(field)) {
19405						self.clearFieldError(field);
19406					}
19407				});
19408			});
19409		};
19410
19411		this.init = function (form) {
19412			var self = this;
19413
19414			self.initFields(form);
19415
19416			$(form).on('submit', function(e) {
19417				e.preventDefault();
19418				e.stopPropagation();
19419
19420				self.clearErrors(form);
19421
19422				var formModal = $(form).parents('.modal[role="dialog"]').first();
19423
19424				if ($(formModal).length) {
19425					$(formModal).on('show.bs.modal hidden.bs.modal', function() {
19426						self.clearErrors(form);
19427					});
19428
19429					/*
19430                 * Make this optional if the form is used for editing
19431                 */
19432					$(formModal).on('show.bs.modal', function() {
19433						$(form)[0].reset();
19434					});
19435				}
19436
19437				WHMCS.http.client.post({
19438					url: $(form).attr('action'),
19439					data: $(form).serializeArray(),
19440				})
19441					.done(function (response) {
19442						self.onSuccess(form, response);
19443					})
19444					.fail(function (jqXHR) {
19445						self.onError(form, jqXHR);
19446					})
19447					.always(function (data) {
19448						self.onRequestComplete(form, data);
19449					});
19450			});
19451		};
19452
19453		this.initAll = function () {
19454			var self = this;
19455
19456			$('form[data-role="json-form"]').each(function() {
19457				var formElement = this;
19458				self.init(formElement);
19459			});
19460		};
19461
19462		this.markFieldErrors = function (form, fields)
19463		{
19464			var self = this;
19465			var errorMessage = null;
19466			var field, fieldLookup;
19467
19468			for (var fieldName in fields) {
19469				if (fields.hasOwnProperty(fieldName)) {
19470					errorMessage = fields[fieldName];
19471				}
19472
19473				fieldLookup = self.managedElements.split(',').map(function(element) {
19474					return element + '[name="' + fieldName + '"]';
19475				}).join(',');
19476
19477				field = $(form).find(fieldLookup);
19478
19479				if (errorMessage) {
19480					$(field).parents('.form-group').addClass('has-error');
19481					$(field).attr('title', errorMessage);
19482					$(field).tooltip();
19483				}
19484			}
19485
19486			$(form).find('.form-group.has-error input[title]').first().tooltip('show');
19487		};
19488
19489		this.fieldHasError = function (field) {
19490			return $(field).parents('.form-group').hasClass('has-error');
19491		};
19492
19493		this.clearFieldError = function (field) {
19494			/**
19495			 * Try dispose first for BS 4, which will raise error
19496			 * on BS 3 or older, then we use destroy instead
19497			 */
19498			try {
19499				$(field).tooltip('dispose');
19500			} catch (err) {
19501				$(field).tooltip('destroy');
19502			}
19503			$(field).parents('.form-group').removeClass('has-error');
19504		};
19505
19506		this.onSuccess = function (form, response) {
19507			var formOnSuccess = $(form).data('on-success');
19508
19509			if (typeof formOnSuccess === 'function') {
19510				formOnSuccess(response.data);
19511			}
19512		};
19513
19514		this.onError = function (form, jqXHR) {
19515			if (jqXHR.responseJSON && jqXHR.responseJSON.fields && typeof jqXHR.responseJSON.fields === 'object') {
19516				this.markFieldErrors(form, jqXHR.responseJSON.fields);
19517			} else {
19518				// TODO: replace with client-accessible generic error messaging
19519				console.log('Unknown error - please try again later.');
19520			}
19521
19522			var formOnError = $(form).data('on-error');
19523
19524			if (typeof formOnError === 'function') {
19525				formOnError(jqXHR);
19526			}
19527		};
19528
19529		this.clearErrors = function (form) {
19530			var self = this;
19531
19532			$(form).find(self.managedElements).each(function () {
19533				self.clearFieldError(this);
19534			})
19535		};
19536
19537		this.onRequestComplete = function (form, data) {
19538			// implement as needed
19539		};
19540
19541		return this;
19542	},
19543
19544	effects: function () {
19545		this.errorShake = function (element) {
19546			/**
19547			 * Shake effect without jQuery UI inspired by Hiren Patel | ninty9notout:
19548			 * @see https://github.com/ninty9notout/jquery-shake/blob/51f3dcf625970c78505bcac831fd9e28fc85d374/jquery.ui.shake.js
19549			 */
19550			options = options || {};
19551			var options = $.extend({
19552				direction: "left",
19553				distance: 8,
19554				times: 3,
19555				speed: 90
19556			}, options);
19557
19558			return element.each(function () {
19559				var el = $(this), props = {
19560					position: el.css("position"),
19561					top: el.css("top"),
19562					bottom: el.css("bottom"),
19563					left: el.css("left"),
19564					right: el.css("right")
19565				};
19566
19567				el.css("position", "relative");
19568
19569				var ref = (options.direction === "up" || options.direction === "down") ? "top" : "left";
19570				var motion = (options.direction === "up" || options.direction === "left") ? "pos" : "neg";
19571
19572				var animation = {}, animation1 = {}, animation2 = {};
19573				animation[ref] = (motion === "pos" ? "-=" : "+=") + options.distance;
19574				animation1[ref] = (motion === "pos" ? "+=" : "-=") + options.distance * 2;
19575				animation2[ref] = (motion === "pos" ? "-=" : "+=") + options.distance * 2;
19576
19577				el.animate(animation, options.speed);
19578				for (var i = 1; i < options.times; i++) {
19579					el.animate(animation1, options.speed).animate(animation2, options.speed);
19580				}
19581
19582				el.animate(animation1, options.speed).animate(animation, options.speed / 2, function () {
19583					el.css(props);
19584				});
19585			});
19586		};
19587
19588	}
19589}
19589);
19590
19591/**
19592 * Form module
19593 *
19594 * @copyright Copyright (c) WHMCS Limited 2005-2017
19595 * @license http://www.whmcs.com/license/ WHMCS Eula
19596 */
19597(function(module) {
19598	if (!WHMCS.hasModule('form')) {
19599		WHMCS.loadModule('form', module);
19600	}
19601})(
19602	function () {
19603		this.checkAllBound = false;
19604
19605		this.register = function () {
19606			if (!this.checkAllBound) {
19607				this.bindCheckAll();
19608				this.checkAllBound = true;
19609			}
19610		};
19611
19612		this.bindCheckAll = function ()
19613		{
19614			var huntSelector = '.btn-check-all';
19615			jQuery('body').on('click', huntSelector, function (e) {
19616				var btn = jQuery(e.target);
19617				var targetInputs = jQuery(
19618					'#' + btn.data('checkbox-container') + ' input[type="checkbox"]'
19619				);
19620				if (btn.data('btn-check-toggle')) {
19621					// one control that changes
19622					var textDeselect = 'Deselect All';
19623					var textSelect = 'Select All';
19624					if (btn.data('label-text-deselect')) {
19625						textDeselect = btn.data('label-text-deselect');
19626					}
19627					if (btn.data('label-text-select')) {
19628						textSelect = btn.data('label-text-select');
19629					}
19630
19631					if (btn.hasClass('toggle-active')) {
19632						targetInputs.prop('checked',false);
19633						btn.text(textSelect);
19634						btn.removeClass('toggle-active');
19635					} else {
19636						targetInputs.prop('checked',true);
19637						btn.text(textDeselect);
19638						btn.addClass('toggle-active');
19639					}
19640				} else {
19641					// two controls that are static
19642					if (btn.data('btn-toggle-on')) {
19643						targetInputs.prop('checked',true);
19644					} else {
19645						targetInputs.prop('checked',false);
19646					}
19647				}
19648			});
19649		};
19650
19651		this.reloadCaptcha = function (element)
19652		{
19653			if (typeof grecaptcha !== 'undefined') {
19654				grecaptcha.reset();
19655			} else {
19656				if (!element) {
19657					element = jQuery('#inputCaptchaImage');
19658				}
19659
19660				var src = jQuery(element).data('src');
19661				jQuery(element).attr('src', src + '?nocache=' + (new Date()).getTime());
19662
19663				var userInput = jQuery('#inputCaptcha');
19664				if (userInput.length) {
19665					userInput.val('');
19666				}
19667			}
19668		};
19669
19670		return this;
19671	});
19672
19673/**
19674 * reCaptcha module
19675 *
19676 * @copyright Copyright (c) WHMCS Limited 2005-2020
19677 * @license http://www.whmcs.com/license/ WHMCS Eula
19678 */
19679var recaptchaLoadComplete = false,
19680	recaptchaCount = 0,
19681	recaptchaType = 'recaptcha',
19682	recaptchaValidationComplete = false;
19683
19684(function(module) {
19685	if (!WHMCS.hasModule('recaptcha')) {
19686		WHMCS.loadModule('recaptcha', module);
19687	}
19688})(
19689	function () {
19690
19691		this.register = function () {
19692			if (recaptchaLoadComplete) {
19693				return;
19694			}
19695			var postLoad = [],
19696				recaptchaForms = jQuery(".btn-recaptcha").parents('form'),
19697				isInvisible = false;
19698			recaptchaForms.each(function (i, el){
19699				if (typeof recaptchaSiteKey === 'undefined') {
19700					console.log('Recaptcha site key not defined');
19701					return;
19702				}
19703				recaptchaCount += 1;
19704				var frm = jQuery(el),
19705					btnRecaptcha = frm.find(".btn-recaptcha"),
19706					required = (typeof requiredText !== 'undefined') ? requiredText : 'Required',
19707					recaptchaId = 'divDynamicRecaptcha' + recaptchaCount;
19708
19709				isInvisible = btnRecaptcha.hasClass('btn-recaptcha-invisible')
19710
19711				// if no recaptcha element, make one
19712				var recaptchaContent = frm.find('#' + recaptchaId + ' .g-recaptcha'),
19713					recaptchaElement = frm.find('.recaptcha-container'),
19714					appendElement = frm;
19715
19716				if (recaptchaElement.length) {
19717					recaptchaElement.attr('id', recaptchaElement.attr('id') + recaptchaCount);
19718					appendElement = recaptchaElement;
19719				}
19720				if (!recaptchaContent.length) {
19721					appendElement.append('<div id="#' + recaptchaId + '" class="g-recaptcha"></div>');
19722					recaptchaContent = appendElement.find('#' + recaptchaId);
19723				}
19724				// propagate invisible recaptcha if necessary
19725				if (!isInvisible) {
19726					recaptchaContent.data('toggle', 'tooltip')
19727						.data('placement', 'bottom')
19728						.data('trigger', 'manual')
19729						.attr('title', required)
19730						.hide();
19731				}
19732
19733
19734				// alter form to work around JS behavior on .submit() when there
19735				// there is an input with the name 'submit'
19736				var btnSubmit = frm.find("input[name='submit']");
19737				if (btnSubmit.length) {
19738					var action = frm.prop('action');
19739					frm.prop('action', action + '&submit=1');
19740					btnSubmit.remove();
19741				}
19742
19743				// make callback for grecaptcha to invoke after
19744				// injecting token & make it known via data-callback
19745				var funcName = recaptchaId + 'Callback';
19746				window[funcName] = function () {
19747					if (isInvisible) {
19748						frm.submit();
19749					}
19750				};
19751
19752				// setup an on form submit event to ensure that we
19753				// are allowing required field validation to occur before
19754				// we do the invisible recaptcha checking
19755				if (isInvisible) {
19756					recaptchaType = 'invisible';
19757					frm.on('submit.recaptcha', function (event) {
19758						var recaptchaId = frm.find('.g-recaptcha').data('recaptcha-id');
19759						if (!grecaptcha.getResponse(recaptchaId).trim()) {
19760							event.preventDefault();
19761							grecaptcha.execute(recaptchaId);
19762							recaptchaValidationComplete = false;
19763						} else {
19764							recaptchaValidationComplete = true;
19765						}
19766					});
19767				} else {
19768					postLoad.push(function () {
19769						recaptchaContent.slideDown('fast', function() {
19770							// just in case there's a delay in DOM; rare
19771							recaptchaContent.find(':first').addClass('center-block');
19772						});
19773					});
19774					postLoad.push(function() {
19775						recaptchaContent.find(':first').addClass('center-block');
19776					});
19777				}
19778			});
19779
19780			window.recaptchaLoadCallback = function() {
19781				jQuery('.g-recaptcha').each(function(i, el) {
19782					var element = jQuery(el),
19783						frm = element.closest('form'),
19784						btn = frm.find('.btn-recaptcha'),
19785						idToUse = element.attr('id').substring(1);
19786					var recaptchaId = grecaptcha.render(
19787						el,
19788						{
19789							sitekey: recaptchaSiteKey,
19790							size: (btn.hasClass('btn-recaptcha-invisible')) ? 'invisible' : 'normal',
19791							callback: idToUse + 'Callback'
19792						}
19793					);
19794					element.data('recaptcha-id', recaptchaId);
19795				});
19796			}
19797
19798			// fetch/invoke the grecaptcha lib
19799			if (recaptchaForms.length) {
19800				var gUrl = "https://www.google.com/recaptcha/api.js?onload=recaptchaLoadCallback&render=explicit";
19801				jQuery.getScript(gUrl, function () {
19802					for(var i = postLoad.length - 1; i >= 0 ; i--){
19803						postLoad[i]();
19804					}
19805				});
19806			}
19807			recaptchaLoadComplete = true;
19808		};
19809
19810		return this;
19811	});
19812/**
19813 * WHMCS client area checkout and invoice payment UX module integration interface.
19814 * Stability: alpha - no guarantees are made against the stability of this interface.
19815 * @copyright Copyright (c) WHMCS Limited 2005-2023
19816 * @license http://www.whmcs.com/license/ WHMCS Eula
19817 */
19818(function(module) {
19819	if (!WHMCS.hasModule('payment')) {
19820		WHMCS.loadModule('payment', module);
19821	}
19822})({
19823
19824	internal: function () {
19825
19826		this.isRenderSource = function (source) {
19827			return [
19828				'checkout',
19829				'invoice-pay',
19830				'admin-payment-method-add',
19831				'admin-payment-method-edit',
19832				'payment-method-add',
19833				'payment-method-edit',
19834			].includes(source);
19835		}
19836
19837		this.reportUnknownSource = function (source) {
19838			if (!WHMCS.payment.internal.isRenderSource(source)) {
19839				WHMCS.payment.internal.logError('unknown source: ' + source);
19840				return true;
19841			}
19842			return false;
19843		}
19844
19845		this.logError = function (error) {
19846			console.error('[WHMCS.payment] ' + error);
19847		}
19848	},
19849
19850	handler: function () {
19851		this.make = function (moduleName) {
19852			function Handler(moduleName) {
19853				this.module = moduleName;
19854
19855				this.onGatewayInit = function (fn, options = {}) {
19856					var eventOptions = {...WHMCS.payment.register.defaultEventOpts(), ...options};
19857					WHMCS.payment.register.onGatewayInit(this.module, fn, eventOptions);
19858					return this;
19859				}
19860
19861				this.onGatewayOptionInit = function (fn, options = {}) {
19862					var eventOptions = {...WHMCS.payment.register.defaultEventOpts(), ...options};
19863					WHMCS.payment.register.onGatewayOptionInit(this.module, fn, eventOptions);
19864					return this;
19865				}
19866
19867				this.onGatewaySelected = function (fn, options = {}) {
19868					var eventOptions = {...WHMCS.payment.register.defaultEventOpts(), ...options};
19869					WHMCS.payment.register.onGatewaySelected(this.module, fn, eventOptions);
19870					return this;
19871				}
19872
19873				this.onGatewayUnselected = function (fn, options = {}) {
19874					var eventOptions = {...WHMCS.payment.register.defaultEventOpts(), ...options};
19875					WHMCS.payment.register.onGatewayUnselected(this.module, fn, eventOptions);
19876					return this;
19877				}
19878
19879				this.onCheckoutFormSubmit = function (fn, options = {}) {
19880					var eventOptions = {...WHMCS.payment.register.defaultEventOpts(), ...options};
19881					WHMCS.payment.register.onCheckoutFormSubmit(this.module, fn, eventOptions);
19882					return this;
19883				}
19884				this.onAddPayMethodFormSubmit = function (fn, options = {}) {
19885					var eventOptions = {...WHMCS.payment.register.defaultEventOpts(), ...options};
19886					WHMCS.payment.register.onAddPayMethodFormSubmit(this.module, fn, eventOptions);
19887					return this;
19888				}
19889
19890				this.manageInputsContainer = function (selector, options = {}) {
19891					var eventOptions = {
19892						...WHMCS.payment.register.defaultEventOpts(),
19893						...{priority: 1},
19894						...options
19895					};
19896					this.onGatewayInit(function (metadata, element) {
19897						if (metadata._source != 'invoice-pay') return;
19898						WHMCS.payment.display.reset();
19899						WHMCS.payment.display.show(jQuery(selector));
19900					}, eventOptions);
19901					this.onGatewaySelected(function (metadata, element) {
19902						if (metadata._source == 'payment-method-add') {
19903							WHMCS.payment.display.reset();
19904							jQuery('div.fieldgroup-creditcard'
19905								+ ',div.fieldgroup-bankaccount'
19906								+ ',div.fieldgroup-auxfields').hide();
19907						}
19908						WHMCS.payment.display.show(jQuery(selector));
19909					}, eventOptions);
19910					this.onGatewayUnselected(function (metadata, element) {
19911						WHMCS.payment.display.hide(jQuery(selector));
19912					}, eventOptions);
19913					return this;
19914				}
19915			}
19916			return new Handler(moduleName);
19917		}
19918	},
19919
19920	register: function () {
19921
19922		this.onGatewayInit = function (module, fn, options) {
19923			if (!this.isFunction('register.gatewayInit', fn)) return this;
19924			this.registerForEvent(
19925				WHMCS.payment.event.observersGatewayInit,
19926				module,
19927				fn,
19928				options
19929			)
19930			return this;
19931		}
19932
19933		this.onGatewayOptionInit = function (module, fn, options) {
19934			if (!this.isFunction('register.gatewayOptionInit', fn)) return this;
19935			this.registerForEvent(
19936				WHMCS.payment.event.observersGatewayOptionInit,
19937				module,
19938				fn,
19939				options
19940			)
19941			return this;
19942		}
19943
19944		this.onGatewaySelected = function (module, fn, options) {
19945			if (!this.isFunction('register.onGatewaySelected', fn)) return this;
19946			this.registerForEvent(
19947				WHMCS.payment.event.observersGatewaySelected,
19948				module,
19949				fn,
19950				options
19951			)
19952			return this;
19953		}
19954
19955		this.onGatewayUnselected = function (module, fn, options) {
19956			if (!this.isFunction('register.onGatewayUnselected', fn)) return this;
19957			this.registerForEvent(
19958				WHMCS.payment.event.observersGatewayUnselected,
19959				module,
19960				fn,
19961				options
19962			)
19963			return this;
19964		}
19965
19966		this.onCheckoutFormSubmit = function (module, fn, options) {
19967			if (!this.isFunction('register.onCheckoutFormSubmit', fn)) return this;
19968			this.registerForEvent(
19969				WHMCS.payment.event.observersCheckoutFormSubmit,
19970				module,
19971				fn,
19972				options
19973			)
19974			return this;
19975		}
19976
19977		this.onAddPayMethodFormSubmit = function (module, fn, options) {
19978			if (!this.isFunction('register.onAddPayMethodFormSubmit', fn)) return this;
19979			this.registerForEvent(
19980				WHMCS.payment.event.observersAddPayMethodFormSubmit,
19981				module,
19982				fn,
19983				options
19984			)
19985			return this;
19986		}
19987
19988		this.defaultEventOpts = function () {
19989			return {
19990				priority: 100,
19991				once: false,
19992			};
19993		}
19994
19995		this.registerForEvent = function (observerMap, module, fn, options) {
19996			if (!observerMap.has(module)) {
19997				observerMap.set(module, new Map);
19998			}
19999			observerMap.get(module).set(options.priority, {
20000				_fn: fn,
20001				...options,
20002			});
20003			return this;
20004		}
20005
20006		this.isFunction = function (label, fn) {
20007			if (typeof fn != 'function') {
20008				console.error('[register.' + label + '] Expecting a function, got ' + fn);
20009				return false;
20010			}
20011			return true;
20012		}
20013	},
20014
20015	event: function () {
20016		this.observersGatewayInit = new Map;
20017		this.observersGatewayOptionInit = new Map;
20018		this.observersGatewaySelected = new Map;
20019		this.observersGatewayUnselected = new Map;
20020		this.observersCheckoutFormSubmit = new Map;
20021		this.observersAddPayMethodFormSubmit = new Map;
20022		this.previouslySelected = null;
20023
20024		this.gatewayInit = function (metadata, module) {
20025			this.notifyEvent(
20026				'gatewayInit',
20027				this.observersGatewayInit,
20028				module,
20029				metadata
20030			);
20031		}
20032
20033		this.gatewayOptionInit = function (metadata, module, formElement) {
20034			this.notifyEvent(
20035				'gatewayOptionInit',
20036				this.observersGatewayOptionInit,
20037				module,
20038				metadata,
20039				formElement
20040			);
20041		}
20042
20043		this.gatewaySelected = function (metadata, module, formElement) {
20044			this.previouslySelected = {
20045				formElement: formElement,
20046				module: module,
20047			};
20048			this.notifyEvent(
20049				'gatewaySelected',
20050				this.observersGatewaySelected,
20051				module,
20052				metadata,
20053				formElement
20054			);
20055		}
20056
20057		this.gatewayUnselected = function (metadata) {
20058			if (this.previouslySelected == null) return;
20059			this.notifyEvent(
20060				'gatewayUnselected',
20061				this.observersGatewayUnselected,
20062				this.previouslySelected.module,
20063				metadata,
20064				this.previouslySelected.formElement
20065			);
20066		}
20067
20068		this.checkoutFormSubmit = function (metadata, module, formElement) {
20069			this.notifyEvent(
20070				'checkoutFormSubmit',
20071				this.observersCheckoutFormSubmit,
20072				module,
20073				metadata,
20074				formElement
20075			);
20076		}
20077
20078		this.addPayMethodFormSubmit = function (metadata, module, formElement) {
20079			this.notifyEvent(
20080				'addPayMethodFormSubmit',
20081				this.observersAddPayMethodFormSubmit,
20082				module,
20083				metadata,
20084				formElement
20085			);
20086		}
20087
20088		this.notifyEvent = function (eventName, observersMap, module, metadata, formElement) {
20089			if (!observersMap.has(module)) {
20090				return;
20091			}
20092			var observers = observersMap.get(module);
20093			var destruct = [];
20094			this.notifyOrdered(observers, function (observer, priority) {
20095				observer._fn(metadata, formElement);
20096				if (observer.once) {
20097					destruct.push(priority);
20098				}
20099			});
20100			destruct.forEach(function (k) {
20101				observers.delete(k);
20102			})
20103		}
20104
20105		this.notifyOrdered = function (observersMap, fn) {
20106			(new Map([...observersMap.entries()].sort())).forEach(fn);
20107		}
20108	},
20109
20110	query: function () {
20111
20112		this.isGatewaySelected = function (module) {
20113			return (
20114				WHMCS.payment.event.previouslySelected != null
20115				&& WHMCS.payment.event.previouslySelected.module == module
20116			);
20117		}
20118
20119	},
20120
20121	behavior: function () {
20122
20123		this.disableDefaultCardValidation = function (source) {
20124			if (source == 'invoice-pay') {
20125				if (typeof validateCreditCardInput === 'function') {
20126					jQuery('#frmPayment').off('submit', validateCreditCardInput);
20127				}
20128			} else if (source == 'checkout') {
20129				if (typeof validateCheckoutCreditCardInput === 'function') {
20130					jQuery('#frmCheckout').off('submit', validateCheckoutCreditCardInput);
20131				}
20132			} else {
20133				WHMCS.payment.internal.reportUnknownSource(source);
20134			}
20135		}
20136
20137		this.enableDefaultCardValidation = function (source) {
20138			if (source == 'invoice-pay') {
20139				if (typeof validateCreditCardInput === 'function') {
20140					jQuery('#frmPayment').on('submit', validateCreditCardInput);
20141				}
20142			} else if (source == 'checkout') {
20143				if (typeof validateCheckoutCreditCardInput === 'function') {
20144					jQuery('#frmCheckout').on('submit', validateCheckoutCreditCardInput);
20145				}
20146			} else {
20147				WHMCS.payment.internal.reportUnknownSource(source);
20148			}
20149		}
20150
20151	},
20152
20153	display: function () {
20154
20155		this.reset = function () {
20156			var container = jQuery('#paymentGatewayInput');
20157			if (container.length == 0) return;
20158			var existing = container.children();
20159			existing.hide();
20160			jQuery('body').append(existing);
20161			return this;
20162		}
20163
20164		this.show = function (inputContainer) {
20165			var container = jQuery('#paymentGatewayInput');
20166			if (container.length == 0) return;
20167			container.append(inputContainer);
20168			inputContainer.slideDown();
20169			return this;
20170		}
20171
20172		this.hide = function (inputContainer) {
20173			inputContainer.slideUp({
20174				complete: function () {
20175					jQuery('body').append(inputContainer);
20176				},
20177			});
20178			return this;
20179		}
20180
20181		this.error = function (errorMessage) {
20182			jQuery('.gateway-errors').html(errorMessage);
20183			return this;
20184		}
20185
20186		this.errorClear = function () {
20187			let gatewayErrorsContainer = jQuery('.gateway-errors');
20188			if (gatewayErrorsContainer.length == 0) return;
20189			this.error('');
20190			gatewayErrorsContainer.slideUp();
20191			return this;
20192		}
20193
20194		this.errorShow = function (errorMessage) {
20195			let gatewayErrorsContainer = jQuery('.gateway-errors');
20196			if (gatewayErrorsContainer.length == 0) return;
20197			this.error(errorMessage);
20198			gatewayErrorsContainer.slideDown()
20199			return this;
20200		}
20201
20202		this.submitReset = function (source) {
20203			if (source == 'invoice-pay') {
20204				this.invoiceSubmitReset();
20205			} else if (source == 'checkout') {
20206				this.checkoutSubmitReset();
20207			} else {
20208				WHMCS.payment.internal.reportUnknownSource(source);
20209			}
20210		};
20211
20212		this.invoiceSubmitReset = function () {
20213			let btnSubmit = jQuery('#btnSubmit').prop('disabled', false)
20214				.removeClass('disabled');
20215			btnSubmit.find('.click-text').hide();
20216			btnSubmit.find('.pay-text').show();
20217		}
20218
20219		this.checkoutSubmitReset = function () {
20220			jQuery('#btnCompleteOrder').removeClass('disabled')
20221				.removeClass('disable-on-click')
20222				.removeClass('spinner-on-click')
20223				.addClass('disable-on-click spinner-on-click')
20224				.prop('disabled', false)
20225				.find('i.fas')
20226				.removeAttr('class')
20227				.addClass('fas fa-arrow-circle-right');
20228		}
20229
20230		this.submitDisable = function (source) {
20231			if (source == 'invoice-pay') {
20232				this.invoiceSubmitDisable();
20233			} else if (source == 'checkout') {
20234				this.checkoutSubmitDisable();
20235			} else {
20236				WHMCS.payment.internal.reportUnknownSource(source);
20237			}
20238		};
20239
20240		this.invoiceSubmitDisable = function () {
20241			jQuery('#btnSubmit').addClass('disabled')
20242				.prop('disabled', true);
20243		}
20244
20245		this.checkoutSubmitDisable = function () {
20246			jQuery('#btnCompleteOrder').addClass('disabled')
20247				.prop('disabled', true);
20248		}
20249	},
20250
20251});
20252/**
20253 * microplugin.js
20254 * Copyright (c) 2013 Brian Reavis & contributors
20255 *
20256 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
20257 * file except in compliance with the License. You may obtain a copy of the License at:
20258 * http://www.apache.org/licenses/LICENSE-2.0
20259 *
20260 * Unless required by applicable law or agreed to in writing, software distributed under
20261 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
20262 * ANY KIND, either express or implied. See the License for the specific language
20263 * governing permissions and limitations under the License.
20264 *
20265 * @author Brian Reavis <[email protected]>
20266 */
20267
20268(function(root, factory) {
20269	if (typeof define === 'function' && define.amd) {
20270		define(factory);
20271	} else if (typeof exports === 'object') {
20272		module.exports = factory();
20273	} else {
20274		root.MicroPlugin = factory();
20275	}
20276}(this, function() {
20277	var MicroPlugin = {};
20278
20279	MicroPlugin.mixin = function(Interface) {
20280		Interface.plugins = {};
20281
20282		/**
20283		 * Initializes the listed plugins (with options).
20284		 * Acceptable formats:
20285		 *
20286		 * List (without options):
20287		 *   ['a', 'b', 'c']
20288		 *
20289		 * List (with options):
20290		 *   [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
20291		 *
20292		 * Hash (with options):
20293		 *   {'a': { ... }, 'b': { ... }, 'c': { ... }}
20294		 *
20295		 * @param {mixed} plugins
20296		 */
20297		Interface.prototype.initializePlugins = function(plugins) {
20298			var i, n, key;
20299			var self  = this;
20300			var queue = [];
20301
20302			self.plugins = {
20303				names     : [],
20304				settings  : {},
20305				requested : {},
20306				loaded    : {}
20307			};
20308
20309			if (utils.isArray(plugins)) {
20310				for (i = 0, n = plugins.length; i < n; i++) {
20311					if (typeof plugins[i] === 'string') {
20312						queue.push(plugins[i]);
20313					} else {
20314						self.plugins.settings[plugins[i].name] = plugins[i].options;
20315						queue.push(plugins[i].name);
20316					}
20317				}
20318			} else if (plugins) {
20319				for (key in plugins) {
20320					if (plugins.hasOwnProperty(key)) {
20321						self.plugins.settings[key] = plugins[key];
20322						queue.push(key);
20323					}
20324				}
20325			}
20326
20327			while (queue.length) {
20328				self.require(queue.shift());
20329			}
20330		};
20331
20332		Interface.prototype.loadPlugin = function(name) {
20333			var self    = this;
20334			var plugins = self.plugins;
20335			var plugin  = Interface.plugins[name];
20336
20337			if (!Interface.plugins.hasOwnProperty(name)) {
20338				throw new Error('Unable to find "' +  name + '" plugin');
20339			}
20340
20341			plugins.requested[name] = true;
20342			plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
20343			plugins.names.push(name);
20344		};
20345
20346		/**
20347		 * Initializes a plugin.
20348		 *
20349		 * @param {string} name
20350		 */
20351		Interface.prototype.require = function(name) {
20352			var self = this;
20353			var plugins = self.plugins;
20354
20355			if (!self.plugins.loaded.hasOwnProperty(name)) {
20356				if (plugins.requested[name]) {
20357					throw new Error('Plugin has circular dependency ("' + name + '")');
20358				}
20359				self.loadPlugin(name);
20360			}
20361
20362			return plugins.loaded[name];
20363		};
20364
20365		/**
20366		 * Registers a plugin.
20367		 *
20368		 * @param {string} name
20369		 * @param {function} fn
20370		 */
20371		Interface.define = function(name, fn) {
20372			Interface.plugins[name] = {
20373				'name' : name,
20374				'fn'   : fn
20375			};
20376		};
20377	};
20378
20379	var utils = {
20380		isArray: Array.isArray || function(vArg) {
20381			return Object.prototype.toString.call(vArg) === '[object Array]';
20382		}
20383	};
20384
20385	return MicroPlugin;
20386}));
20387/**
20388 * sifter.js
20389 * Copyright (c) 2013 Brian Reavis & contributors
20390 *
20391 * Licensed under the Apache License, Version 2.0 (the "License");
20391 you may not use this
20392 * file except in compliance with the License. You may obtain a copy of the License at:
20393 * http://www.apache.org/licenses/LICENSE-2.0
20394 *
20395 * Unless required by applicable law or agreed to in writing, software distributed under
20396 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
20397 * ANY KIND, either express or implied. See the License for the specific language
20398 * governing permissions and limitations under the License.
20399 *
20400 * @author Brian Reavis <[email protected]>
20401 */
20402
20403(function(root, factory) {
20404	if (typeof define === 'function' && define.amd) {
20405		define(
vendor: 10,020 bytes, lines 20405-20810
20405factory);
20406	} else if (typeof exports === 'object') {
20407		module.exports = factory();
20408	} else {
20409		root.Sifter = factory();
20410	}
20411}(this, function() {
20412
20413	/**
20414	 * Textually searches arrays and hashes of objects
20415	 * by property (or multiple properties). Designed
20416	 * specifically for autocomplete.
20417	 *
20418	 * @constructor
20419	 * @param {array|object} items
20420	 * @param {object} items
20421	 */
20422	var Sifter = function(items, settings) {
20423		this.items = items;
20424		this.settings = settings || {diacritics: true};
20425	};
20426
20427	/**
20428	 * Splits a search string into an array of individual
20429	 * regexps to be used to match results.
20430	 *
20431	 * @param {string} query
20432	 * @returns {array}
20433	 */
20434	Sifter.prototype.tokenize = function(query) {
20435		query = trim(String(query || '').toLowerCase());
20436		if (!query || !query.length) return [];
20437
20438		var i, n, regex, letter;
20439		var tokens = [];
20440		var words = query.split(/ +/);
20441
20442		for (i = 0, n = words.length; i < n; i++) {
20443			regex = escape_regex(words[i]);
20444			if (this.settings.diacritics) {
20445				for (letter in DIACRITICS) {
20446					if (DIACRITICS.hasOwnProperty(letter)) {
20447						regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]);
20448					}
20449				}
20450			}
20451			tokens.push({
20452				string : words[i],
20453				regex  : new RegExp(regex, 'i')
20454			});
20455		}
20456
20457		return tokens;
20458	};
20459
20460	/**
20461	 * Iterates over arrays and hashes.
20462	 *
20463	 * ```
20464	 * this.iterator(this.items, function(item, id) {
20465	 *    // invoked for each item
20466	 * });
20467	 * ```
20468	 *
20469	 * @param {array|object} object
20470	 */
20471	Sifter.prototype.iterator = function(object, callback) {
20472		var iterator;
20473		if (is_array(object)) {
20474			iterator = Array.prototype.forEach || function(callback) {
20475				for (var i = 0, n = this.length; i < n; i++) {
20476					callback(this[i], i, this);
20477				}
20478			};
20479		} else {
20480			iterator = function(callback) {
20481				for (var key in this) {
20482					if (this.hasOwnProperty(key)) {
20483						callback(this[key], key, this);
20484					}
20485				}
20486			};
20487		}
20488
20489		iterator.apply(object, [callback]);
20490	};
20491
20492	/**
20493	 * Returns a function to be used to score individual results.
20494	 *
20495	 * Good matches will have a higher score than poor matches.
20496	 * If an item is not a match, 0 will be returned by the function.
20497	 *
20498	 * @param {object|string} search
20499	 * @param {object} options (optional)
20500	 * @returns {function}
20501	 */
20502	Sifter.prototype.getScoreFunction = function(search, options) {
20503		var self, fields, tokens, token_count, nesting;
20504
20505		self        = this;
20506		search      = self.prepareSearch(search, options);
20507		tokens      = search.tokens;
20508		fields      = search.options.fields;
20509		token_count = tokens.length;
20510		nesting     = search.options.nesting;
20511
20512		/**
20513		 * Calculates how close of a match the
20514		 * given value is against a search token.
20515		 *
20516		 * @param {mixed} value
20517		 * @param {object} token
20518		 * @return {number}
20519		 */
20520		var scoreValue = function(value, token) {
20521			var score, pos;
20522
20523			if (!value) return 0;
20524			value = String(value || '');
20525			pos = value.search(token.regex);
20526			if (pos === -1) return 0;
20527			score = token.string.length / value.length;
20528			if (pos === 0) score += 0.5;
20529			return score;
20530		};
20531
20532		/**
20533		 * Calculates the score of an object
20534		 * against the search query.
20535		 *
20536		 * @param {object} token
20537		 * @param {object} data
20538		 * @return {number}
20539		 */
20540		var scoreObject = (function() {
20541			var field_count = fields.length;
20542			if (!field_count) {
20543				return function() { return 0; };
20544			}
20545			if (field_count === 1) {
20546				return function(token, data) {
20547					return scoreValue(getattr(data, fields[0], nesting), token);
20548				};
20549			}
20550			return function(token, data) {
20551				for (var i = 0, sum = 0; i < field_count; i++) {
20552					sum += scoreValue(getattr(data, fields[i], nesting), token);
20553				}
20554				return sum / field_count;
20555			};
20556		})();
20557
20558		if (!token_count) {
20559			return function() { return 0; };
20560		}
20561		if (token_count === 1) {
20562			return function(data) {
20563				return scoreObject(tokens[0], data);
20564			};
20565		}
20566
20567		if (search.options.conjunction === 'and') {
20568			return function(data) {
20569				var score;
20570				for (var i = 0, sum = 0; i < token_count; i++) {
20571					score = scoreObject(tokens[i], data);
20572					if (score <= 0) return 0;
20573					sum += score;
20574				}
20575				return sum / token_count;
20576			};
20577		} else {
20578			return function(data) {
20579				for (var i = 0, sum = 0; i < token_count; i++) {
20580					sum += scoreObject(tokens[i], data);
20581				}
20582				return sum / token_count;
20583			};
20584		}
20585	};
20586
20587	/**
20588	 * Returns a function that can be used to compare two
20589	 * results, for sorting purposes. If no sorting should
20590	 * be performed, `null` will be returned.
20591	 *
20592	 * @param {string|object} search
20593	 * @param {object} options
20594	 * @return function(a,b)
20595	 */
20596	Sifter.prototype.getSortFunction = function(search, options) {
20597		var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort;
20598
20599		self   = this;
20600		search = self.prepareSearch(search, options);
20601		sort   = (!search.query && options.sort_empty) || options.sort;
20602
20603		/**
20604		 * Fetches the specified sort field value
20605		 * from a search result item.
20606		 *
20607		 * @param  {string} name
20608		 * @param  {object} result
20609		 * @return {mixed}
20610		 */
20611		get_field = function(name, result) {
20612			if (name === '$score') return result.score;
20613			return getattr(self.items[result.id], name, options.nesting);
20614		};
20615
20616		// parse options
20617		fields = [];
20618		if (sort) {
20619			for (i = 0, n = sort.length; i < n; i++) {
20620				if (search.query || sort[i].field !== '$score') {
20621					fields.push(sort[i]);
20622				}
20623			}
20624		}
20625
20626		// the "$score" field is implied to be the primary
20627		// sort field, unless it's manually specified
20628		if (search.query) {
20629			implicit_score = true;
20630			for (i = 0, n = fields.length; i < n; i++) {
20631				if (fields[i].field === '$score') {
20632					implicit_score = false;
20633					break;
20634				}
20635			}
20636			if (implicit_score) {
20637				fields.unshift({field: '$score', direction: 'desc'});
20638			}
20639		} else {
20640			for (i = 0, n = fields.length; i < n; i++) {
20641				if (fields[i].field === '$score') {
20642					fields.splice(i, 1);
20643					break;
20644				}
20645			}
20646		}
20647
20648		multipliers = [];
20649		for (i = 0, n = fields.length; i < n; i++) {
20650			multipliers.push(fields[i].direction === 'desc' ? -1 : 1);
20651		}
20652
20653		// build function
20654		fields_count = fields.length;
20655		if (!fields_count) {
20656			return null;
20657		} else if (fields_count === 1) {
20658			field = fields[0].field;
20659			multiplier = multipliers[0];
20660			return function(a, b) {
20661				return multiplier * cmp(
20662					get_field(field, a),
20663					get_field(field, b)
20664				);
20665			};
20666		} else {
20667			return function(a, b) {
20668				var i, result, a_value, b_value, field;
20669				for (i = 0; i < fields_count; i++) {
20670					field = fields[i].field;
20671					result = multipliers[i] * cmp(
20672						get_field(field, a),
20673						get_field(field, b)
20674					);
20675					if (result) return result;
20676				}
20677				return 0;
20678			};
20679		}
20680	};
20681
20682	/**
20683	 * Parses a search query and returns an object
20684	 * with tokens and fields ready to be populated
20685	 * with results.
20686	 *
20687	 * @param {string} query
20688	 * @param {object} options
20689	 * @returns {object}
20690	 */
20691	Sifter.prototype.prepareSearch = function(query, options) {
20692		if (typeof query === 'object') return query;
20693
20694		options = extend({}, options);
20695
20696		var option_fields     = options.fields;
20697		var option_sort       = options.sort;
20698		var option_sort_empty = options.sort_empty;
20699
20700		if (option_fields && !is_array(option_fields)) options.fields = [option_fields];
20701		if (option_sort && !is_array(option_sort)) options.sort = [option_sort];
20702		if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty];
20703
20704		return {
20705			options : options,
20706			query   : String(query || '').toLowerCase(),
20707			tokens  : this.tokenize(query),
20708			total   : 0,
20709			items   : []
20710		};
20711	};
20712
20713	/**
20714	 * Searches through all items and returns a sorted array of matches.
20715	 *
20716	 * The `options` parameter can contain:
20717	 *
20718	 *   - fields {string|array}
20719	 *   - sort {array}
20720	 *   - score {function}
20721	 *   - filter {bool}
20722	 *   - limit {integer}
20723	 *
20724	 * Returns an object containing:
20725	 *
20726	 *   - options {object}
20727	 *   - query {string}
20728	 *   - tokens {array}
20729	 *   - total {int}
20730	 *   - items {array}
20731	 *
20732	 * @param {string} query
20733	 * @param {object} options
20734	 * @returns {object}
20735	 */
20736	Sifter.prototype.search = function(query, options) {
20737		var self = this, value, score, search, calculateScore;
20738		var fn_sort;
20739		var fn_score;
20740
20741		search  = this.prepareSearch(query, options);
20742		options = search.options;
20743		query   = search.query;
20744
20745		// generate result scoring function
20746		fn_score = options.score || self.getScoreFunction(search);
20747
20748		// perform search and sort
20749		if (query.length) {
20750			self.iterator(self.items, function(item, id) {
20751				score = fn_score(item);
20752				if (options.filter === false || score > 0) {
20753					search.items.push({'score': score, 'id': id});
20754				}
20755			});
20756		} else {
20757			self.iterator(self.items, function(item, id) {
20758				search.items.push({'score': 1, 'id': id});
20759			});
20760		}
20761
20762		fn_sort = self.getSortFunction(search, options);
20763		if (fn_sort) search.items.sort(fn_sort);
20764
20765		// apply limits
20766		search.total = search.items.length;
20767		if (typeof options.limit === 'number') {
20768			search.items = search.items.slice(0, options.limit);
20769		}
20770
20771		return search;
20772	};
20773
20774	// utilities
20775	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20776
20777	var cmp = function(a, b) {
20778		if (typeof a === 'number' && typeof b === 'number') {
20779			return a > b ? 1 : (a < b ? -1 : 0);
20780		}
20781		a = asciifold(String(a || ''));
20782		b = asciifold(String(b || ''));
20783		if (a > b) return 1;
20784		if (b > a) return -1;
20785		return 0;
20786	};
20787
20788	var extend = function(a, b) {
20789		var i, n, k, object;
20790		for (i = 1, n = arguments.length; i < n; i++) {
20791			object = arguments[i];
20792			if (!object) continue;
20793			for (k in object) {
20794				if (object.hasOwnProperty(k)) {
20795					a[k] = object[k];
20796				}
20797			}
20798		}
20799		return a;
20800	};
20801
20802	/**
20803	 * A property getter resolving dot-notation
20804	 * @param  {Object}  obj     The root object to fetch property on
20805	 * @param  {String}  name    The optionally dotted property name to fetch
20806	 * @param  {Boolean} nesting Handle nesting or not
20807	 * @return {Object}          The resolved property value
20808	 */
20809	var getattr = function(obj, name, nesting) {
20810	
vendor: 2,804 bytes, lines 20810-20883
20810	if (!obj || !name) return;
20811		if (!nesting) return obj[name];
20812		var names = name.split(".");
20813		while(names.length && (obj = obj[names.shift()]));
20814		return obj;
20815	};
20816
20817	var trim = function(str) {
20818		return (str + '').replace(/^\s+|\s+$|/g, '');
20819	};
20820
20821	var escape_regex = function(str) {
20822		return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
20823	};
20824
20825	var is_array = Array.isArray || (typeof $ !== 'undefined' && $.isArray) || function(object) {
20826		return Object.prototype.toString.call(object) === '[object Array]';
20827	};
20828
20829	var DIACRITICS = {
20830		'a': '[aḀḁĂăÂâǍǎȺⱥȦȧẠạÄäÀàÁáĀāÃãÅåąĄÃąĄ]',
20831		'b': '[b␢βΒB฿𐌁ᛒ]',
20832		'c': '[cĆćĈĉČčĊċC̄c̄ÇçḈḉȻȼƇƈɕᴄCc]',
20833		'd': '[dĎďḊḋḐḑḌḍḒḓḎḏĐđD̦d̦ƉɖƊɗƋƌᵭᶁᶑȡᴅDdð]',
20834		'e': '[eÉéÈèÊêḘḙĚěĔĕẼẽḚḛẺẻĖėËëĒēȨȩĘęᶒɆɇȄȅẾếỀềỄễỂểḜḝḖḗḔḕȆȇẸẹỆệⱸᴇEeɘǝƏƐε]',
20835		'f': '[fƑƒḞḟ]',
20836		'g': '[gɢ₲ǤǥĜĝĞğĢģƓɠĠġ]',
20837		'h': '[hĤĥĦħḨḩẖẖḤḥḢḣɦʰǶƕ]',
20838		'i': '[iÍíÌìĬĭÎîǏǐÏïḮḯĨĩĮįĪīỈỉȈȉȊȋỊịḬḭƗɨɨ̆ᵻᶖİiIıɪIi]',
20839		'j': '[jȷĴĵɈɉʝɟʲ]',
20840		'k': '[kƘƙꝀꝁḰḱǨǩḲḳḴḵκϰ₭]',
20841		'l': '[lŁłĽľĻļĹĺḶḷḸḹḼḽḺḻĿŀȽƚⱠⱡⱢɫɬᶅɭȴʟLl]',
20842		'n': '[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲȠƞᵰᶇɳȵɴNnŊŋ]',
20843		'o': '[oØøÖöÓóÒòÔôǑǒŐőŎŏȮȯỌọƟɵƠơỎỏŌōÕõǪǫȌȍՕօ]',
20844		'p': '[pṔṕṖṗⱣᵽƤƥᵱ]',
20845		'q': '[qꝖꝗʠɊɋꝘꝙq̃]',
20846		'r': '[rŔŕɌɍŘřŖŗṘṙȐȑȒȓṚṛⱤɽ]',
20847		's': '[sŚśṠṡṢṣꞨꞩŜŝŠšŞşȘșS̈s̈]',
20848		't': '[tŤťṪṫŢţṬṭƮʈȚțṰṱṮṯƬƭ]',
20849		'u': '[uŬŭɄʉỤụÜüÚúÙùÛûǓǔŰűŬŭƯưỦủŪūŨũŲųȔȕ∪]',
20850		'v': '[vṼṽṾṿƲʋꝞꝟⱱʋ]',
20851		'w': '[wẂẃẀẁŴŵẄẅẆẇẈẉ]',
20852		'x': '[xẌẍẊẋχ]',
20853		'y': '[yÝýỲỳŶŷŸÿỸỹẎẏỴỵɎɏƳƴ]',
20854		'z': '[zŹźẐẑŽžŻżẒẓẔẕƵƶ]'
20855	};
20856
20857	var asciifold = (function() {
20858		var i, n, k, chunk;
20859		var foreignletters = '';
20860		var lookup = {};
20861		for (k in DIACRITICS) {
20862			if (DIACRITICS.hasOwnProperty(k)) {
20863				chunk = DIACRITICS[k].substring(2, DIACRITICS[k].length - 1);
20864				foreignletters += chunk;
20865				for (i = 0, n = chunk.length; i < n; i++) {
20866					lookup[chunk.charAt(i)] = k;
20867				}
20868			}
20869		}
20870		var regexp = new RegExp('[' +  foreignletters + ']', 'g');
20871		return function(str) {
20872			return str.replace(regexp, function(foreignletter) {
20873				return lookup[foreignletter];
20874			}).toLowerCase();
20875		};
20876	})();
20877
20878
20879	// export
20880	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20881
20882	return Sifter;
20883}
20883));
20884
20885
20886/**
20887 * General utilities module
20888 *
20889 * @copyright Copyright (c) WHMCS Limited 2005-2017
20890 * @license http://www.whmcs.com/license/ WHMCS Eula
20891 */
20892(function(module) {
20893	if (!WHMCS.hasModule('utils')) {
20894		WHMCS.loadModule('utils', module);
20895	}
20896})(
20897	function () {
20898		/**
20899		 * Not crypto strong; server-side must discard for
20900		 * something with more entropy; the value is sufficient
20901		 * for strong client-side validation check
20902		 */
20903		this.simpleRNG = function () {
20904			var chars = './$_-#!,^*()|';
20905			var r = 0;
20906			for (var i = 0; r < 3; i++) {
20907				r += Math.floor((Math.random() * 10) / 2);
20908			}
20909			r = Math.floor(r);
20910			var s = '';
20911			for (var x = 0; x < r; x++) {
20912				v = (Math.random() + 1).toString(24).split('.')[1];
20913				if ((Math.random()) > 0.5) {
20914					s += btoa(v).substr(0,4)
20915				} else {
20916					s += v
20917				}
20918
20919				if ((Math.random()) > 0.5) {
20920					s += chars.substr(
20921						Math.floor(Math.random() * 13),
20922						1
20923					);
20924				}
20925			}
20926
20927			return s;
20928		};
20929
20930		this.getRouteUrl = function (path) {
20931			return whmcsBaseUrl + "/index.php?rp=" + path;
20932		};
20933
20934		this.validateBaseUrl = function() {
20935			if (typeof window.whmcsBaseUrl === 'undefined') {
20936				console.log('Warning: The WHMCS Base URL definition is missing '
20937					+ 'from your active template. Please refer to '
20938					+ 'https://docs.whmcs.com/WHMCS_Base_URL_Template_Variable '
20939					+ 'for more information and details of how to resolve this '
20940					+ 'warning.');
20941				window.whmcsBaseUrl = this.autoDetermineBaseUrl();
20942				window.whmcsBaseUrlAutoSet = true;
20943			} else if (window.whmcsBaseUrl === ''
20944				&& typeof window.whmcsBaseUrlAutoSet !== 'undefined'
20945				&& window.whmcsBaseUrlAutoSet === true
20946			) {
20947				window.whmcsBaseUrl = this.autoDetermineBaseUrl();
20948			}
20949		};
20950
20951		this.autoDetermineBaseUrl = function() {
20952			var windowLocation = window.location.href;
20953			var phpExtensionLocation = -1;
20954
20955			if (typeof windowLocation !== 'undefined') {
20956				phpExtensionLocation = windowLocation.indexOf('.php');
20957			}
20958
20959			if (phpExtensionLocation === -1) {
20960				windowLocation = jQuery('#Primary_Navbar-Home a').attr('href');
20961				if (typeof windowLocation !== 'undefined') {
20962					phpExtensionLocation = windowLocation.indexOf('.php');
20963				}
20964			}
20965
20966			if (phpExtensionLocation !== -1) {
20967				windowLocation = windowLocation.substring(0, phpExtensionLocation);
20968				var lastTrailingSlash = windowLocation.lastIndexOf('/');
20969				if (lastTrailingSlash !== false) {
20970					return windowLocation.substring(0, lastTrailingSlash);
20971				}
20972			}
20973
20974			return '';
20975		};
20976
20977		this.normaliseStringValue = function(status) {
20978			return status ? status.toLowerCase().replace(/\s/g, '-') : '';
20979		};
20980
20981		this.generatePassword = function(len) {
20982			var charset = this.getPasswordCharacterSet();
20983			var result = "";
20984			for (var i = 0; len > i; i++)
20985				result += charset[this.randomInt(charset.length)];
20986			return result;
20987		};
20988		this.getPasswordCharacterSet = function() {
20989			var rawCharset = '0123456789'
20990				+ 'abcdefghijklmnopqrstuvwxyz'
20991				+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
20992				+ '!#$%()*+,-.:;=@_|{ldelim}{rdelim}~';
20993
20994			// Parse UTF-16, remove duplicates, convert to array of strings
20995			var charset = [];
20996			for (var i = 0; rawCharset.length > i; i++) {
20997				var c = rawCharset.charCodeAt(i);
20998				if (0xD800 > c || c >= 0xE000) {  // Regular UTF-16 character
20999					var s = rawCharset.charAt(i);
21000					if (charset.indexOf(s) == -1)
21001						charset.push(s);
21002					continue;
21003				}
21004				if (0xDC00 > c ? rawCharset.length > i + 1 : false) {  // High surrogate
21005					var d = rawCharset.charCodeAt(i + 1);
21006					if (d >= 0xDC00 ? 0xE000 > d : false) {  // Low surrogate
21007						var s = rawCharset.substring(i, i + 2);
21008						i++;
21009						if (charset.indexOf(s) == -1)
21010							charset.push(s);
21011						continue;
21012					}
21013				}
21014				throw "Invalid UTF-16";
21015			}
21016			return charset;
21017		};
21018		this.randomInt = function(n) {
21019			var x = this.randomIntMathRandom(n);
21020			x = (x + this.randomIntBrowserCrypto(n)) % n;
21021			return x;
21022		};
21023		this.randomIntMathRandom = function(n) {
21024			var x = Math.floor(Math.random() * n);
21025			if (0 > x || x >= n)
21026				throw "Arithmetic exception";
21027			return x;
21028		};
21029		this.randomIntBrowserCrypto = function(n) {
21030			var cryptoObject = null;
21031
21032			if ("crypto" in window)
21033				cryptoObject = crypto;
21034			else if ("msCrypto" in window)
21035				cryptoObject = msCrypto;
21036			else
21037				return 0;
21038
21039			if (!("getRandomValues" in cryptoObject) || !("Uint32Array" in window) || typeof Uint32Array != "function")
21040				cryptoObject = null;
21041
21042			if (cryptoObject == null)
21043				return 0;
21044
21045			// Generate an unbiased sample
21046			var x = new Uint32Array(1);
21047			do cryptoObject.getRandomValues(x);
21048			while (x[0] - x[0] % n > 4294967296 - n);
21049			return x[0] % n;
21050		};
21051
21052		return this;
21053	});
21054
21055WHMCS.utils.validateBaseUrl();
21056
21057/*!
21058 * WHMCS Twenty-One Theme
21059 * Global Javascript
21060 * Copyright (c) 2020 WHMCS Limited
21061 * https://www.whmcs.com/license/
21062 */
21063
21064jQuery(document).ready(function() {
21065
21066	// when the page loads
21067	autoCollapse('#nav', 30);
21068
21069	if (jQuery('#lightbox').length === 0) {
21070		lightbox.init();
21071	}
21072
21073	// when the window is resized
21074	jQuery(window).on('resize', function () {
21075		if (jQuery('button[data-target="#mainNavbar"], button[data-toggle="collapse"]').is(':visible')) {
21076			return;
21077		}
21078		autoCollapse('#nav', 30);
21079	});
21080
21081	// Item selector
21082	jQuery('.item-selector .item').click(function(e) {
21083		e.preventDefault();
21084		jQuery(this).closest('.item-selector').find('.item').removeClass('active').end()
21085			.find('input').val(jQuery(this).data('value'));
21086		jQuery(this).addClass('active');
21087	});
21088
21089	// Password reveal
21090	jQuery(document).on('click', '.btn-reveal-pw', function (e) {
21091		$targetField = jQuery(this).closest('.input-group').find('.pw-input');
21092		if ($targetField.attr('type') == 'password') {
21093			$targetField.attr('type', 'text');
21094		} else {
21095			$targetField.attr('type', 'password');
21096		}
21097	});
21098
21099	// Account notifications popover
21100	jQuery("#accountNotifications").popover({
21101		container: 'body',
21102		placement: 'bottom',
21103		template: '<div class="popover popover-user-notifications" role="tooltip"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-header"></h3><div class="popover-body"><p></p></div></div></div>',
21104		html: true,
21105		content: function() {
21106			return jQuery("#accountNotificationsContent").html();
21107		},
21108	});
21109
21110	jQuery('.card-sidebar .truncate').each(function () {
21111		jQuery(this).attr('title', jQuery(this).text())
21112			.attr('data-toggle', 'tooltip')
21113			.attr('data-placement', 'bottom');
21114	});
21115
21116	// Default catch for all other popovers
21117	jQuery('[data-toggle="popover"]').popover({
21118		html: true
21119	});
21120
21121	// Enable tooltips
21122	// Attach function to body so tooltips inserted by ajax will load
21123	jQuery(function(jQuery){
21124		jQuery('body').tooltip({
21125			selector: '[data-toggle="tooltip"]'
21126		});
21127	});
21128
21129	// Logic to dismiss popovers on click outside
21130	jQuery('body').on('click', function (e) {
21131		jQuery('[data-toggle="popover"]').each(function () {
21132			if (!jQuery(this).is(e.target) && jQuery(this).has(e.target).length === 0 && jQuery('.popover').has(e.target).length === 0) {
21133				jQuery(this).popover('hide');
21134			}
21135		});
21136	});
21137
21138	// Sidebar active class toggle
21139	jQuery(".list-group-tab-nav a").click(function() {
21140		if (jQuery(this).hasClass('disabled')) {
21141			return false;
21142		}
21143		var urlFragment = this.href.split('#')[1];
21144		if (urlFragment) {
21145			// set the fragment in the URL bar for bookmarking and such.
21146			window.location.hash = '#' + urlFragment;
21147		}
21148	});
21149
21150	// Sidebar minimise/maximise
21151	jQuery('.card-minimise').click(function(e) {
21152		e.preventDefault();
21153		var collapsableBody = jQuery(this).closest('.card').find('.collapsable-card-body');
21154		if (jQuery(this).hasClass('minimised')) {
21155			collapsableBody.slideDown();
21156			jQuery(this).removeClass('minimised');
21157		} else {
21158			collapsableBody.slideUp();
21159			jQuery(this).addClass('minimised');
21160		}
21161	});
21162
21163	// Minimise sidebar panels by default on small devices
21164	if (jQuery('.container').width() <= 720) {
21165		jQuery('.card-sidebar').find('.collapsable-card-body').hide().end()
21166			.find('.card-minimise').addClass('minimised');
21167	}
21168
21169	// Internal page tab selection handling via location hash
21170	var internalSelectionDisabled = false;
21171	if (
21172		typeof(disableInternalTabSelection) !== 'undefined'
21173		&&
21174		disableInternalTabSelection
21175	) {
21176		internalSelectionDisabled = true;
21177	}
21178
21179	if (!internalSelectionDisabled) {
21180		if (jQuery(location).attr('hash').substr(1) !== "") {
21181			var activeTab = jQuery(location).attr('hash');
21182			jQuery(".primary-content > .tab-content > .tab-pane").removeClass('active');
21183			jQuery(activeTab).removeClass('fade').addClass('active');
21184			jQuery(".list-group-tab-nav a").removeClass('active');
21185			jQuery('a[href="' + activeTab + '"]').addClass('active');
21186			setTimeout(function() {
21187				// Browsers automatically scroll on page load with a fragment.
21188				// This scrolls back to the top right after page complete, but
21189				// just before render (no perceptible scroll).
21190				window.scrollTo(0, 0);
21191			}, 1);
21192		}
21193	}
21194
21195	// Enable Switches for Checkboxes
21196	if (jQuery.prototype.bootstrapSwitch) {
21197		jQuery(".toggle-switch-success").bootstrapSwitch({
21198			onColor: 'success'
21199		});
21200	}
21201
21202	// Collapsable Panels
21203	jQuery(".panel-collapsable .card-header").click(function(e) {
21204		var $this = jQuery(this);
21205		if (!$this.closest('.card').hasClass('panel-collapsed')) {
21206			$this.closest('.card').addClass('panel-collapsed').find('.card-body').slide
21206Up();
21207			$this.find('.collapse-icon i').removeClass('fa-minus').addClass('fa-plus');
21208		} else {
21209			$this.closest('.card').removeClass('panel-collapsed').find('.card-body').slideDown();
21210			$this.find('.collapse-icon i').removeClass('fa-plus').addClass('fa-minus');
21211		}
21212	});
21213
21214	// Two-Factor Authentication Auto Focus Rules
21215	if (("#frmLogin").length > 0) {
21216		jQuery("#frmLogin input:text:visible:first").focus();
21217	}
21218	if (("#twofaactivation").length > 0) {
21219		jQuery("#twofaactivation input:text:visible:first,#twofaactivation input:password:visible:first").focus();
21220	}
21221
21222	// Sub-Account Activation Toggle
21223	jQuery("#inputSubaccountActivate").click(function () {
21224		if (jQuery("#inputSubaccountActivate:checked").val() != null) {
21225			jQuery("#subacct-container").show();
21226		} else {
21227			jQuery("#subacct-container").hide();
21228		}
21229	});
21230
21231	// Mass Domain Management Bulk Action Handling
21232	jQuery(".setBulkAction").click(function(event) {
21233		event.preventDefault();
21234		var id = jQuery(this).attr('id').replace('Link', ''),
21235			domainForm = jQuery('#domainForm');
21236
21237		if (id === 'renewDomains') {
21238			domainForm.attr('action', WHMCS.utils.getRouteUrl('/cart/domain/renew'));
21239		} else {
21240			if (jQuery('#' + id).length !== 0) {
21241				var action = domainForm.attr('action');
21242				domainForm.attr('action', action + '#' + id);
21243			}
21244			jQuery('#bulkaction').val(id);
21245		}
21246		domainForm.submit();
21247	});
21248
21249	// Stop events on objects with this class from bubbling up the dom
21250	jQuery('.stopEventBubble').click( function(event) {
21251		event.stopPropagation();
21252	});
21253
21254	// Tab Control Link handling for tab switching via regular links
21255	jQuery('.tabControlLink').on(
21256		'click',
21257		function(event) {
21258			event.preventDefault();
21259			var id = jQuery(this).attr('href');
21260			jQuery("a[href='/"+id+"']").click();
21261		}
21262	);
21263
21264	jQuery(document).on('click', '.delete-cc-email', function() {
21265		var self = jQuery(this),
21266			email = self.data('email'),
21267			feedback = jQuery('#divCcEmailFeedback');
21268
21269		if (feedback.is(':visible')) {
21270			feedback.slideUp('fast');
21271		}
21272
21273		WHMCS.http.jqClient.jsonPost({
21274			url: window.location.href,
21275			data: {
21276				action: 'delete',
21277				email: email,
21278				token: csrfToken
21279			},
21280			success: function (data) {
21281				if (data.success) {
21282					self.closest('.ticket-cc-email').parent('div').slideUp('fast').remove();
21283					feedback.removeClass('alert-danger')
21284						.addClass('alert-success')
21285						.html(data.message)
21286						.slideDown('fast');
21287				}
21288			},
21289			error: function (error) {
21290				if (error) {
21291					feedback.removeClass('alert-success')
21292						.addClass('alert-danger')
21293						.html(error)
21294						.slideDown('fast');
21295				}
21296			}
21297		});
21298	}).on('submit', '#frmAddCcEmail', function(e) {
21299		e.preventDefault();
21300		var frm = jQuery(this),
21301			cloneRow = jQuery('#ccCloneRow').clone().removeAttr('id'),
21302			email = jQuery('#inputAddCcEmail'),
21303			feedback = jQuery('#divCcEmailFeedback');
21304
21305		if (feedback.is(':visible')) {
21306			feedback.slideUp('fast');
21307		}
21308		WHMCS.http.jqClient.jsonPost({
21309			url: frm.attr('action'),
21310			data: frm.serialize(),
21311			success: function (data) {
21312				if (data.success) {
21313					cloneRow.find('span.email')
21314						.html(email.val())
21315						.find('button')
21316						.data('email', email.val())
21317						.end();
21318
21319					cloneRow.show()
21320						.appendTo(jQuery('#sidebarTicketCc').find('.list-group'));
21321					email.val('');
21322					feedback.slideUp('fast')
21323						.removeClass('alert-danger hidden')
21324						.addClass('alert-success')
21325						.html(data.message)
21326						.slideDown('fast');
21327				}
21328			},
21329			error: function (error) {
21330				if (error) {
21331					feedback.slideUp('fast')
21332						.removeClass('alert-success hidden')
21333						.addClass('alert-danger')
21334						.html(error)
21335						.slideDown('fast');
21336				}
21337			}
21338		});
21339	});
21340
21341	// Ticket Rating Click Handler
21342	jQuery('.ticket-reply .rating span.star').click( function(event) {
21343		window.location = 'viewticket.php?tid='
21344			+ jQuery(this).parent('.rating').attr("ticketid")
21345			+ '&c=' + jQuery(this).parent('.rating').attr("ticketkey")
21346			+ '&rating=rate' + jQuery(this).parent('.rating').attr("ticketreplyid")
21347			+ '_' + jQuery(this).attr("rate");
21348	});
21349
21350	// Prevent malicious window.opener activity from auto-linked URLs
21351	jQuery('a.autoLinked').click(function (e) {
21352		e.preventDefault();
21353		if (jQuery(this).hasClass('disabled')) {
21354			return false;
21355		}
21356
21357		var child = window.open();
21358		child.opener = null;
21359		child.location = e.target.href;
21360	});
21361
21362	// Handle Single Sign-On Toggle Setting
21363	jQuery("#inputAllowSso").on('switchChange.bootstrapSwitch', function(event, isChecked) {
21364		if (isChecked) {
21365			jQuery("#ssoStatusTextEnabled").show();
21366			jQuery("#ssoStatusTextDisabled").hide();
21367		} else {
21368			jQuery("#ssoStatusTextDisabled").show();
21369			jQuery("#ssoStatusTextEnabled").hide();
21370		}
21371		WHMCS.http.jqClient.post("clientarea.php", jQuery("#frmSingleSignOn").serialize());
21372	});
21373
21374	// Single Sign-On call for Product/Service
21375	jQuery('.btn-service-sso').on('click', function(e) {
21376		e.preventDefault();
21377		var button = jQuery(this);
21378
21379		var form = button.closest('form');
21380
21381		if (form.length === 0) {
21382			form = button.find('form');
21383		}
21384		if (form.hasClass('disabled') || button.hasClass('disabled')) {
21385			return;
21386		}
21387		var url = form.data('href');
21388		if (!url) {
21389			url = window.location.href;
21390		}
21391
21392		button.attr('disabled', 'disabled').addClass('disabled');
21393		jQuery('.loading', button).show().end();
21394		jQuery('.login-feedback', form).slideUp();
21395		WHMCS.http.jqClient.post(
21396			url,
21397			form.serialize(),
21398			function (data) {
21399				jQuery('.loading', button).hide().end().removeAttr('disabled');
21400				jQuery('.login-feedback', form).html('');
21401				if (data.error) {
21402					jQuery('.login-feedback', form).hide().html(data.error).slideDown();
21403				}
21404				if (data.redirect !== undefined && data.redirect.substr(0, 7) === 'window|') {
21405					window.open(data.redirect.substr(7), '_blank');
21406				}
21407			},
21408			'json'
21409		).always(function() {
21410			button.removeAttr('disabled').removeClass('disabled');
21411			button.find('.loading').hide().end();
21412		});
21413	});
21414	jQuery('.btn-sidebar-form-submit').on('click', function(e) {
21415		e.preventDefault();
21416		jQuery(this).find('.loading').show().end()
21417			.attr('disabled', 'disabled');
21418
21419		var form = jQuery(this).closest('form');
21420
21421		if (form.length === 0) {
21422			form = jQuery(this).find('form');
21423		}
21424
21425		if (form.length !== 0 && form.hasClass('disabled') === false) {
21426			form.submit();
21427		} else {
21428			jQuery(this).find('.loading').hide().end().removeAttr('disabled');
21429		}
21430	});
21431
21432	// Back to top animated scroll
21433	jQuery('.back-to-top').click(function(e) {
21434		e.preventDefault();
21435		jQuery('body,html').animate({scrollTop: 0}, 500);
21436	});
21437
21438	// Prevent page scroll on language choose click
21439	jQuery('.choose-language').click(function(e) {
21440		e.preventDefault();
21441	});
21442
21443	// Activate copy to clipboard functionality
21444	jQuery('.copy-to-clipboard').click(WHMCS.ui.clipboard.copy);
21445
21446	// Handle Language Chooser modal
21447	jQuery('#modalChooseLanguage button[type=submit]').click(function(e) {
21448		e.preventDefault();
21449		var form = jQuery(this).closest('form');
21450		var currency = form.find('input[name="currency"]');
21451		var language = form.find('input[name="language"]');
21452		var fields = [];
21453
21454		if (language.data('current') != language.val()) {
21455			fields.push('language=' + language.val());
21456		}
21457		if (currency.data('current') != currency.val() && currency.val() != "") {
21458			fields.push('currency=' + currency.val());
21459		}
21460
21461		window.location.replace(form.attr('action') + fields.join('&'));
21462	});
21463
21464	// Password Generator
21465	jQuery('.generate-password').click(function(e) {
21466		jQuery('#frmGeneratePassword').submit();
21467		jQuery('#modalGeneratePassword')
21468			.data('targetfields', jQuery(this).data('targetfields'))
21469			.modal('show');
21470	});
21471	jQuery('#frmGeneratePassword').submit(function(e) {
21472		e.preventDefault();
21473		var length = parseInt(jQuery('#inputGeneratePasswordLength').val(), 10);
21474
21475		// Check length
21476		if (length < 8 || length > 64) {
21477			jQuery('#generatePwLengthError').show();
21478			return;
21479		}
21480
21481		jQuery('#inputGeneratePasswordOutput').val(WHMCS.utils.generatePassword(length));
21482	});
21483	jQuery('#btnGeneratePasswordInsert')
21484		.click(WHMCS.ui.clipboard.copy)
21485		.click(function(e) {
21486			jQuery(this).closest('.modal').modal('hide');
21487			var targetFields = jQuery(this).closest('.modal').data('targetfields'),
21488				generatedPassword = jQuery('#inputGeneratePasswordOutput');
21489			targetFields = targetFields.split(',');
21490			for(var i = 0; i < targetFields.length; i++) {
21491				jQuery('#' + targetFields[i]).val(generatedPassword.val())
21492					.trigger('keyup');
21493			}
21494			// Remove the generated password.
21495			setTimeout(function(){
21496				generatedPassword.val('');
21497			},1000)
21498		});
21499
21500	/**
21501	 * If we are logged into the admin area and can edit a category and click edit,
21502	 * we need to stop the default and click the edit instead since its nested.
21503	 */
21504	jQuery('a.card-body').click(function(e) {
21505		if (e.target.id.includes('btnEditCategory')) {
21506			e.preventDefault();
21507			var editUrl = jQuery('#btnEditCategory-' + jQuery(this).data('id')).data('url');
21508			window.location.href = editUrl;
21509		}
21510	});
21511
21512	jQuery('.kb-article-item').click(function(e) {
21513		if (e.target.id.includes('btnEditArticle')) {
21514			e.preventDefault();
21515			var editUrl = jQuery('#btnEditArticle-' + jQuery(this).data('id')).data('url');
21516			window.location.href = editUrl;
21517		}
21518	});
21519	/**
21520	 * Code will loop through each element that has the class markdown-editor and
21521	 * enable the Markdown editor.
21522	 */
21523	var count = 0,
21524		editorName = 'clientMDE',
21525		counter = 0;
21526	jQuery(".markdown-editor").each(function( index ) {
21527		count++;
21528		var autoSaveName = jQuery(this).data('auto-save-name'),
21529			footerId = jQuery(this).attr('id') + '-footer';
21530		if (typeof autoSaveName == "undefined") {
21531			autoSaveName = 'client_area';
21532		}
21533		window[editorName + count.toString()] = jQuery(this).markdown(
21534			{
21535				footer: '<div id="' + footerId + '" class="markdown-editor-status"></div>',
21536				autofocus: false,
21537				savable: false,
21538				resize: 'vertical',
21539				iconlibrary: 'fa',
21540				language: locale,
21541				onShow: function(e){
21542					var content = '',
21543						save_enabled = false;
21544					if(typeof(Storage) !== "undefined") {
21545						// Code for localStorage/sessionStorage.
21546						content = localStorage.getItem(autoSaveName);
21547						save_enabled = true;
21548						if (content && typeof(content) !== "undefined") {
21549							e.setContent(content);
21550						}
21551					}
21552					jQuery("#" + footerId).html(parseMdeFooter(content, save_enabled, saved));
21553				},
21554				onChange: function(e){
21555					var content = e.getContent(),
21556						save_enabled = false;
21557					if(typeof(Storage) !== "undefined") {
21558						counter = 3;
21559						save_enabled = true;
21560						localStorage.setItem(autoSaveName, content);
21561						doCountdown();
21562					}
21563					jQuery("#" + footerId).html(parseMdeFooter(content, save_enabled));
21564				},
21565				onPreview: function(e){
21566					var originalContent = e.getContent(),
21567						parsedContent;
21568
21569					jQuery.ajax({
21570						url: WHMCS.utils.getRouteUrl('/clientarea/message/preview'),
21571						async: false,
21572						data: {token: csrfToken, content: originalContent},
21573						dataType: 'json',
21574						success: function (data) {
21575							parsedContent = data;
21576						}
21577					});
21578
21579					return parsedContent.body ? parsedContent.body : '';
21580				},
21581				additionalButtons: [
21582					[{
21583						name: "groupCustom",
21584						data: [{
21585							name: "cmdHelp",
21586							title: "Help",
21587							hotkey: "Ctrl+F1",
21588							btnClass: "btn open-modal",
21589							icon: {
21590								glyph: 'fas fa-question-circle',
21591								fa: 'fa fa-question-circle',
21592								'fa-3': 'icon-question-sign',
21593								'fa-5': 'fas fa-question-circle',
21594							},
21595							callback: function(e) {
21596								e.$editor.removeClass("md-fullscreen-mode");
21597							}
21598						}]
21599					}]
21600				],
21601				hiddenButtons: [
21602					'cmdImage'
21603				]
21604			});
21605
21606		jQuery('button[data-handler="bootstrap-markdown-cmdHelp"]')
21607			.attr('data-modal-title', markdownGuide)
21608			.attr('href', 'submitticket.php?action=markdown');
21609
21610		jQuery(this).closest("form").bind({
21611			submit: function() {
21612				if(typeof(Storage) !== "undefined") {
21613					localStorage.removeItem(autoSaveName);
21614				}
21615			}
21616		});
21617	});
21618
21619	// Email verification
21620	var btnResendEmail = jQuery('.btn-resend-verify-email');
21621	jQuery(btnResendEmail).click(function() {
21622		$(this).prop('disabled', true).find('.loader').show();
21623		WHMCS.http.jqClient.post(
21624			jQuery(this).data('uri'),
21625			{
21626				'token': csrfToken,
21627			}).done(function(data) {
21628			btnResendEmail.find('.loader').hide();
21629			if (data.success) {
21630				btnResendEmail.text(btnResendEmail.data('email-sent'));
21631			} else {
21632				btnResendEmail.text(btnResendEmail.data('error-msg'));
21633			}
21634		});
21635	});
21636	jQuery('#btnEmailVerificationClose').click(function(e) {
21637		e.preventDefault();
21638		WHMCS.http.jqClient.post(jQuery(this).data('uri'),
21639			{
21640				'token': csrfToken
21641			});
21642		jQuery('.verification-banner.email-verification').hide();
21643	});
21644	jQuery('#btnUserValidationClose').click(function(e) {
21645		e.preventDefault();
21646		WHMCS.http.jqClient.post(jQuery(this).data('uri'),
21647			{
21648				'token': csrfToken
21649			});
21650		jQuery('.verification-banner.user-validation').hide();
21651	});
21652
21653	var ssoDropdown = jQuery('#servicesPanel').find('.list-group');
21654	if (parseInt(ssoDropdown.css('height'), 10) < parseInt(ssoDropdown.css('max-height'), 10)) {
21655		ssoDropdown.css('overflow', 'unset');
21656	}
21657
21658
21659	/**
21660	 * Parse the content to populate the markdown editor footer.
21661	 *
21662	 * @param {string} content
21663	 * @param {bool} auto_save
21664	 * @param {string} [saveText]
21665	 * @returns {string}
21666	 */
21667	function parseMdeFooter(content, auto_save, saveText)
21668	{
21669		saveText = saveText || saving;
21670		var pattern = /[^\s]+/g,
21671			m = [],
21672			word_count = 0,
21673			line_count = 0;
21674		if (content) {
21675			m = content.match(pattern);
21676			line_count = content.split(/\\r\\n|\\r|\\n/).length;
21677		}
21678		if (m) {
21679			for (var i = 0; i < m.length; i++) {
21680				if (m[i].charCodeAt(0) >= 0x4E00) {
21681					word_count += m[i].length;
21682				} else {
21683					word_count += 1;
21684				}
21685			}
21686		}
21687		return '<div class="small-font">lines: ' + line_count
21688			+ '&nbsp;&nbsp;&nbsp;words: ' + word_count + ''
21689			+ (auto_save ? '&nbsp;&nbsp;&nbsp;<span class="markdown-save">' + saveText + '</span>' : '')
21690			+ '</div>';
21691	}
21692
21693	/**
21694	 * Countdown the save timeout. When zero, the span will update to show saved.
21695	 */
21696	function doCountdown()
21697	{
21698		if (counter >= 0) {
21699			if (counter === 0) {
21700				jQuery("span.markdown-save").html(saved);
21701			}
21702			counter--;
21703			setTimeout(doCountdown, 1000);
21704		}
21705	}
21706
21707	// Two-Factor Activation Process Modal Handler.
21708	var frmTwoFactorActivation = jQuery('input[name=2fasetup]').parent('form');
21709	frmTwoFactorActivation.submit(function(e) {
21710		e.preventDefault();
21711		openModal(frmTwoFactorActivation.attr('action'), frmTwoFactorActivation.serialize(), 'Loading...');
21712	});
21713
21714	$.fn.setInputError = function(error) {
21715		this.closest('.form-group').addClass('has-error').find('.field-error-msg').text(error);
21716		return this;
21717	};
21718
21719	jQuery.fn.showInputError = function () {
21720		this.closest('.form-group').addClass('has-error').find('.field-error-msg').show();
21721		return this;
21722	};
21723
21724	jQuery('#frmPayment').on('submit', function() {
21725		var btn = jQuery('#btnSubmit');
21726		btn.find('span').toggle();
21727		btn.prop('disabled', true).addClass('disabled');
21728	});
21729
21730	// SSL Manage Action Button.
21731	jQuery('.btn-resend-approver-email').click(function () {
21732		WHMCS.http.jqClient.post(
21733			jQuery(this).data('url'),
21734			{
21735				addonId: jQuery(this).data('addonid'),
21736				serviceId: jQuery(this).data('serviceid'),
21737			},
21738			function(data) {
21739				if (data.success === true) {
21740					jQuery('.alert-table-ssl-manage').addClass('alert-success').text('Approver Email Resent').show();
21741				} else {
21742					jQuery('.alert-table-ssl-manage').addClass('alert-danger').text('Error: ' + data.message).show();
21743				}
21744			}
21745		);
21746	});
21747
21748	// Domain Pricing Table Filters
21749	jQuery(".tld-filters a").click(function(e) {
21750		e.preventDefault();
21751
21752		var noTlds = jQuery('.tld-row.no-tlds');
21753
21754		if (jQuery(this).hasClass('badge-success')) {
21755			jQuery(this).removeClass('badge-success');
21756		} else {
21757			jQuery(this).addClass('badge-success');
21758		}
21759		if (noTlds.is(':visible')) {
21760			noTlds.hide();
21761		}
21762
21763		jQuery('.tld-row').removeClass('filtered-row');
21764		jQuery('.tld-filters a.badge-success').each(function(index) {
21765			var filterValue = jQuery(this).data('category');
21766			jQuery('.tld-row[data-category*="' + filterValue + '"]').addClass('filtered-row');
21767		});
21768		jQuery(".filtered-row:even").removeClass('highlighted');
21769		jQuery(".filtered-row:odd").addClass('highlighted');
21770
21771		var rowsToHide = jQuery('.tld-row:not(".filtered-row")');
21772		rowsToHide.fadeOut('fast');
21773		rowsToHide.promise().done(function () {
21774			if (jQuery('.filtered-row').length === 0) {
21775				noTlds.show();
21776			} else {
21777				jQuery('.tld-row.filtered-row').show();
21778			}
21779		});
21780	});
21781	jQuery(".filtered-row:even").removeClass('highlighted');
21782	jQuery(".filtered-row:odd").addClass('highlighted');
21783
21784	// DataTable data-driven auto object registration
21785	WHMCS.ui.dataTable.register();
21786
21787	WHMCS.ui.jsonForm.initAll();
21788
21789	jQuery(document).on('click', '#btnTicketAttachmentsAdd', function() {
21790		jQuery('#fileUploadsContainer').append(jQuery('.file-upload').html());
21791	});
21792	jQuery(document).on('change', '.custom-file-input', function() {
21793		var fileName = jQuery(this).val().split('\\').pop();
21794		jQuery(this).siblings('.custom-file-label').text(fileName);
21795	});
21796	jQuery('#frmReply').submit(function(e) {
21797		jQuery('#frmReply').find('input[type="submit"]').addClass('disabled').prop('disabled', true);
21798	});
21799
21800	jQuery('#frmDomainContactModification').on('submit', function(){
21801		if (!allowSubmit) {
21802			var changed = false;
21803			jQuery('.irtp-field').each(function() {
21804				var value = jQuery(this).val(),
21805					originalValue = jQuery(this).data('original-value');
21806				if (value !== originalValue) {
21807					changed = true;
21808				}
21809			});
21810			if (changed) {
21811				jQuery('#modalIRTPConfirmation').modal('show');
21812				return false;
21813			}
21814		}
21815		return true;
21816	});
21817
21818	jQuery('.ssl-state.ssl-sync').each(function () {
21819		var self = jQuery(this),
21820			type = getSslAttribute(self, 'type'),
21821			domain = getSslAttribute(self, 'domain');
21822		WHMCS.http.jqClient.post(
21823			WHMCS.utils.getRouteUrl('/domain/ssl-check'),
21824			{
21825				'type': type,
21826				'domain': domain,
21827				'token': csrfToken
21828			},
21829			function (data) {
21830				if (data.invalid) {
21831					self.hide();
21832				} else {
21833					var width = '',
21834						statusDisplayLabel = '';
21835					if (self.attr('width')) {
21836						width = ' width="' + self.attr('width') + '"';
21837					}
21838					if (self.data('showlabel')) {
21839						statusDisplayLabel = ' ' + data.statusDisplayLabel;
21840					}
21841					self.replaceWith(
21842						'<img src="' + data.image + '" data-toggle="tooltip" alt="' + data.tooltip + '" title="' + data.tooltip + '" class="' + data.class + '"' + width + '>'
21843					);
21844					if (data.ssl.status === 'active') {
21845						jQuery('#ssl-startdate').text(data.ssl.startDate);
21846						jQuery('#ssl-expirydate').text(data.ssl.expiryDate);
21847						jQuery('#ssl-issuer').text(data.ssl.issuer);
21848					} else {
21849						jQuery('#ssl-startdate').parent('div').hide();
21850						jQuery('#ssl-expirydate').parent('div').hide();
21851						jQuery('#ssl-issuer').parent('div').hide();
21852					}
21853
21854					jQuery('#statusDisplayLabel').text(statusDisplayLabel);
21855				}
21856			}
21857		);
21858	});
21859
21860	jQuery(document).on('click', '.ssl-state.ssl-inactive', function(e) {
21861		e.preventDefault();
21862		window.location.href = WHMCS.utils.getRouteUrl('/ssl-purchase');
21863	});
21864
21865	WHMCS.recaptcha.register();
21866
21867	var dynamicRecaptchaContainer = jQuery('#divDynamicRecaptcha');
21868	var homepageHasRecaptcha = jQuery(dynamicRecaptchaContainer).length > 0;
21869	var homepageHasInvisibleRecaptcha = homepageHasRecaptcha && jQuery(dynamicRecaptchaContainer).data('size') === 'invisible';
21870
21871	var frmDomainHomepage = jQuery('#frmDomainHomepage');
21872
21873	jQuery(frmDomainHomepage).find('button[data-domain-action="transfer"]').click(function () {
21874		jQuery(frmDomainHomepage).find('input[name="transfer"]').val('1');
21875	});
21876
21877	if (homepageHasRecaptcha && !homepageHasInvisibleRecaptcha) {
21878		jQuery('section#home-banner').addClass('with-recaptcha');
21879	}
21880
21881	if (jQuery('.domainchecker-homepage-captcha').length && !homepageHasInvisibleRecaptcha) {
21882		// invisible reCaptcha doesn't play well with onsubmit() handlers on all submissions following a prevented one
21883
21884		jQuery(frmDomainHomepage).submit(function (e) {
21885			var inputDomain = jQuery(frmDomainHomepage).find('input[name="domain"]'),
21886				reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
21887				reCaptcha = jQuery('#g-recaptcha-response'),
21888				captcha = jQuery('#inputCaptcha');
21889
21890			if (reCaptcha.length && !reCaptcha.val()) {
21891				reCaptchaContainer.tooltip('show');
21892
21893				e.preventDefault();
21894				return;
21895			}
21896
21897			if (captcha.length && !captcha.val()) {
21898				captcha.tooltip('show');
21899
21900				e.preventDefault();
21901			}
21902		});
21903	}
21904
21905	$('.icheck-button').iCheck({
21906		inheritID: true,
21907		checkboxClass: 'icheckbox_square-blue',
21908		radioClass: 'iradio_square-blue',
21909		increaseArea: '20%'
21910	});
21911
21912	jQuery('#inputNoStore').on('switchChange.bootstrapSwitch', function(event, state) {
21913		var descContainer = jQuery('#inputDescription');
21914		if (!state) {
21915			descContainer.prop('disabled', true).addClass('disabled');
21916		}
21917		if (state) {
21918			descContainer.removeClass('disabled').prop('disabled', false);
21919		}
21920	});
21921
21922	jQuery(document).on('click', '#btnConfirmModalConfirmBtn', function () {
21923		var confirmButton = jQuery(this),
21924			confirmationModal = confirmButton.closest('div.modal'),
21925			targetUrl = confirmButton.data('target-url'),
21926			dataTable = confirmButton.closest('table.dataTable[data-on-draw-rebind-confirmation-modal="true"]');
21927		WHMCS.http.jqClient.jsonPost(
21928			{
21929				url: targetUrl,
21930				data: {
21931					token: csrfToken
21932				},
21933				success: function(data) {
21934					if (data.status === 'success' || data.status === 'okay') {
21935						if (dataTable.length > 0) {
21936							dataTable.DataTable().ajax.reload();
21937						}
21938					}
21939				}
21940			}
21941		);
21942		confirmationModal.modal('toggle');
21943	});
21944	hideOverlay();
21945
21946	jQuery('input[name="approval_method"]').on('ifChecked', function(event) {
21947		var fileMethod = $('#containerApprovalMethodFile'),
21948			emailMethod = $('#containerApprovalMethodEmail'),
21949			dnsMethod = $('#containerApprovalMethodDns');
21950		if (jQuery(this).attr('value') == 'file') {
21951			fileMethod.show();
21952			dnsMethod.hide();
21953			emailMethod.hide();
21954		} else if (jQuery(this).attr('value') == 'dns-txt-token') {
21955			dnsMethod.show();
21956			fileMethod.hide();
21957			emailMethod.hide();
21958		} else {
21959			fileMethod.hide();
21960			dnsMethod.hide();
21961			emailMethod.show();
21962		}
21963	});
21964
21965	(function () {
21966		jQuery('.div-service-status').css(
21967			'width',
21968			(jQuery('.div-service-status .label-placeholder').outerWidth() + 5)
21969		);
21970		jQuery('div[menuitemname="Active Products/Services"] .list-group-item:visible')
21971			.last()
21972			.css('border-bottom', '1px solid #ddd');
21973	}());
21974	jQuery('div[menuitemname="Active Products/Services"] .btn-view-more').on('click', function(event) {
21975		var hiddenItems = jQuery('div[menuitemname="Active Products/Services"] .list-group-item:hidden');
21976		var itemAmount = 8;
21977		event.preventDefault();
21978		hiddenItems.slice(0,itemAmount).css('display', 'block');
21979		if ((hiddenItems.length - itemAmount) <= 0) {
21980			jQuery(event.target).addClass('disabled').attr("aria-disabled", true);
21981		}
21982		jQuery('div[menuitemname="Active Products/Services"] .list-group-item:visible')
21983			.css('border-bottom', '')
21984			.last()
21985			.css('border-bottom', '1px solid #ddd');
21986	})
21987	jQuery('div[menuitemname="Service Details Actions"] a[data-identifier][data-serviceid][data-active="1"]').on('click', function(event) {
21988		return customActionAjaxCall(event, jQuery(event.target).closest('a'));
21989	});
21990	jQuery('.div-service-item').on('click', function (event) {
21991		var element = jQuery(event.target);
21992		if (element.is('.dropdown-toggle, .dropdown-menu')) {
21993			return true;
21994		}
21995		if (element.hasClass('btn-custom-action')) {
21996			return customActionAjaxCall(event, element);
21997		}
21998		window.location.href = element.closest('.div-service-item').data('href');
21999		return false;
22000	});
22001});
22002
22003/**
22004 * Control disabled/enabled state of elements by class name.
22005 *
22006 * @param {string} className     Common element class name.
22007 * @param {bool} disabledState   Whether the elements should be disabled or not.
22008 */
22009function disableFields(className, disabledState) {
22010	if (className[0] !== '.') {
22011		className = '.' + className;
22012	}
22013	var elements = jQuery(className);
22014	elements.prop('disabled', disabledState);
22015	if (disabledState) {
22016		elements.addClass('disabled');
22017	} else {
22018		elements.removeClass('disabled');
22019	}
22020}
22021
22022/**
22023 * Check all checkboxes with a given class.
22024 *
22025 * @param {string} className         Common class name.
22026 * @param {Element} masterControl Parent checkbox to which the other checkboxes should mirror.
22027 */
22028function checkAll(className, masterControl) {
22029	if (className[0] !== '.') {
22030		className = '.' + className;
22031	}
22032	// In jQuery, if you set the checked attribute directly, the dom
22033	// element is changed, but browsers don't show the check box as
22034	// checked.  Using the click event will properly display.
22035	jQuery(className).removeAttr('checked');
22036	if(jQuery(masterControl).is(":checked")) {
22037		jQuery(className).click();
22038	}
22039}
22040
22041/**
22042 * Redirect on click if an element is not a button or link.
22043 *
22044 * Where table rows are clickable, we only want to redirect if the row
22045 * itself is clicked. If a button or link within the row is clicked,
22046 * the event tied to that object should be executed. This function
22047 * stops the standard JS event bubbling required to make that happen.
22048 *
22049 * @param {object} clickEvent jQuery click event
22050 * @param {string} target     Redirect location
22051 * @param {bool} newWindow    Open link in new window
22052 */
22053function clickableSafeRedirect(clickEvent, target, newWindow) {
22054	var eventSource = clickEvent.target.tagName.toLowerCase();
22055	var eventParent = clickEvent.target.parentNode.tagName.toLowerCase();
22056	var eventTable = clickEvent.target.parentNode.parentNode.parentNode;
22057	if (jQuery(eventTable).hasClass('collapsed')) {
22058		// This is a mobile device sized display, and datatables has triggered folding
22059		return false;
22060	}
22061	if (eventSource === 'i' && jQuery(clickEvent.target).hasClass('ssl-required')) {
22062		return false;
22063	}
22064	if(eventSource !== 'button' && eventSource !== 'a') {
22065		if(eventParent !== 'button' && eventParent !== 'a') {
22066			if (newWindow) {
22067				window.open(target);
22068			} else {
22069				window.location.href = target;
22070			}
22071		}
22072	}
22073}
22074
22075/**
22076 * Open a centered popup window.
22077 *
22078 * @param {string} addr     The URL to navigate to
22079 * @param {string} popname  The name to assign the window
22080 * @param {number} w        The width
22081 * @param {number} h        The height
22082 * @param {string} features Any additional settings to apply
22083 */
22084function popupWindow(addr, popname, w, h, features) {
22085	var winl = (screen.width-w) / 2,
22086		wint = (screen.height-h) / 2,
22087		win;
22088	if (winl < 0) {
22089		winl = 0;
22090	}
22091	if (wint < 0) {
22092		wint = 0;
22093	}
22094	var settings = 'height=' + h + ',';
22095	settings += 'width=' + w + ',';
22096	settings += 'top=' + wint + ',';
22097	settings += 'left=' + winl + ',';
22098	settings += features;
22099	win = window.open(addr, popname, settings);
22100	win.window.focus();
22101}
22102
22103/**
22104 * Navigate to a page on dropdown change.
22105 *
22106 * This is implemented onblur() for a dropdown.  When the dropdown
22107 * changes state, the value is pulled and the browser navigated to
22108 * the selected page.
22109 *
22110 * @param {Element} select The dropdown triggering the event
22111 */
22112function selectChangeNavigate(select) {
22113	window.location.href = $(select).val();
22114}
22115
22116/**
22117 * Fetch load and uptime for a given server.
22118 *
22119 * @param {number} num Server Id
22120 */
22121function getStats(num) {
22122	WHMCS.http.jqClient.post('serverstatus.php', 'getstats=1&num=' + num, function(data) {
22123		jQuery("#load"+num).html(data.load);
22124		jQuery("#uptime"+num).html(data.uptime);
22125	},'json');
22126}
22127
22128/**
22129 * Determine status of a given port for a given server.
22130 *
22131 * @param {number} num  Server Id
22132 * @param {number} port Port Number
22133 */
22134function checkPort(num, port) {
22135	WHMCS.http.jqClient.post('serverstatus.php', 'ping=1&num=' + num + '&port=' + port, function(data) {
22136		jQuery("#port" + port + "_" + num).html(data);
22137	});
22138}
22139
22140/**
22141 * Fetch automated knowledgebase suggestions for ticket content.
22142 */
22143var currentcheckcontent,
22144	lastcheckcontent;
22145function getticketsuggestions() {
22146	currentcheckcontent = jQuery("#message").val();
22147	if (currentcheckcontent !== lastcheckcontent && currentcheckcontent !== "") {
22148		WHMCS.http.jqClient.post("submitticket.php", { action: "getkbarticles", text: currentcheckcontent },
22149			function(data){
22150				if (data) {
22151					jQuery("#searchresults").html(data).slideDown();
22152				}
22153			});
22154		lastcheckcontent = currentcheckcontent;
22155	}
22156	setTimeout('getticketsuggestions();', 3000);
22157}
22158
22159/**
22160 * Update custom fields upon department change.
22161 *
22162 * @param {Element} input The department selector dropdown object
22163 */
22164function refreshCustomFields(input) {
22165	jQuery("#customFieldsContainer").load(
22166		"submitticket.php",
22167		{ action: "getcustomfields", deptid: $(input).val() }
22168	);
22169}
22170
22171/**
22172 * Submit the first form that exists within a given container.
22173 *
22174 * @param {string} containerId The ID name of the container
22175 */
22176function autoSubmitFormByContainer(containerId) {
22177	if (typeof noAutoSubmit === "undefined" || noAutoSubmit === false) {
22178		jQuery("#" + containerId).find("form:first").submit();
22179	}
22180}
22181
22182/**
22183 * Submit default whois info and disable custom fields.
22184 *
22185 * @param {string} regType The contact registration type
22186 */
22187function useDefaultWhois(regType) {
22188	jQuery("." + regType.substr(0, regType.length - 1) + "customwhois").attr("disabled", true);
22189	jQuery("." + regType.substr(0, regType.length - 1) + "defaultwhois").attr("disabled", false);
22190	jQuery('#' + regType.substr(0, regType.length - 1) + '1').attr("checked", "checked");
22191}
22192
22193/**
22194 * Submit custom fields and disable default whois info.
22195 *
22196 * @param {string} regType The contact registration type
22197 */
22198function useCustomWhois(regType) {
22199	jQuery("." + regType.substr(0, regType.length - 1) + "customwhois").attr("disabled", false);
22200	jQuery("." + regType.substr(0, regType.length - 1) + "defaultwhois").attr("disabled", true);
22201	jQuery('#' + regType.substr(0, regType.length - 1) + '2').attr("checked", "checked");
22202}
22203
22204function showNewBillingAddressFields() {
22205	jQuery('#newBillingAddress').parent('div').slideDown();
22206}
22207
22208function hideNewBillingAddressFields() {
22209	jQuery('#newBillingAddress').parent('div').slideUp();
22210}
22211
22212/**
22213 * Show new credit card input fields.
22214 */
22215function showNewCardInputFields() {
22216	var ccDetails = jQuery('.cc-details'),
22217		ccNumber = jQuery('#inputCardNumber'),
22218		billAddress = jQuery('#billingAddressChoice'),
22219		container;
22220
22221	container = ccDetails.parent('div');
22222	if (container.not(':visible')) {
22223		container.show();
22224	}
22225	jQuery('.cc-details').slideDown();
22226	ccNumber.focus();
22227
22228	container = billAddress.parent('div');
22229	if (container.not(':visible')) {
22230		container.show();
22231	}
22232	billAddress.slideDown()
22233		.find('input[name="billingcontact"]')
22234		.first()
22235		.iCheck('check');
22236}
22237
22238/**
22239 * Show new bank account input fields.
22240 */
22241function showNewAccountInputFields() {
22242	var bankDetails = jQuery('.bank-details').parent('div');
22243	if (bankDetails.not(':visible')) {
22244		bankDetails.slideDown();
22245	}
22246
22247	jQuery("#billingAddressChoice")
22248		.parent('div')
22249		.slideDown()
22250		.find('input[name="billingcontact"]')
22251		.first()
22252		.iCheck('check');
22253}
22254
22255/**
22256 * Hide new credit card input fields.
22257 */
22258function hideNewCardInputFields() {
22259	hideNewBillingAddressFields();
22260	jQuery(".cc-details").slideUp();
22261	jQuery("#billingAddressChoice").slideUp();
22262	var contactId = jQuery('input[name="ccinfo"]:checked').data('billing-contact-id');
22263	if (contactId != undefined) {
22264		jQuery('#billingAddressChoice label.billing-contact-' + contactId)
22265			.iCheck('check');
22266	}
22267	jQuery('#inputCardCvv').focus();
22268}
22269
22270/**
22271 * Hide new bank account input fields.
22272 */
22273function hideNewAccountInputFields() {
22274	hideNewBillingAddressFields();
22275
22276	jQuery(".bank-details").parent('div').slideUp();
22277	jQuery("#billingAddressChoice").parent('div').slideUp();
22278
22279	var selectedAccount = jQuery('input[name="paymethod"]:checked'),
22280		selectedContactId = jQuery(selectedAccount).data('billing-contact-id'),
22281		selectedContactData = jQuery('.billing-contact-info[data-billing-contact-id="' + selectedContactId + '"]');
22282
22283	if (selectedContactData.length) {
22284		jQuery('.billing-contact-info').hide();
22285		jQuery(selectedContactData).show();
22286	}
22287}
22288
22289/**
22290 * Get automatic knowledgebase suggestions for support ticket message.
22291 */
22292var lastTicketMsg;
22293function getTicketSuggestions() {
22294	var userMsg = jQuery("#inputMessage").val();
22295	if (userMsg !== lastTicketMsg && userMsg !== '') {
22296		WHMCS.http.jqClient.post("submitticket.php", { action: "getkbarticles", text: userMsg },
22297			function (data) {
22298				var suggestions = jQuery("#autoAnswerSuggestions");
22299				if (data) {
22300					suggestions.html(data);
22301					if (suggestions.not(":visible")) {
22302						suggestions.slideDown();
22303					}
22304				}
22305			});
22306		lastTicketMsg = userMsg;
22307	}
22308	setTimeout('getTicketSuggestions()', 3000);
22309}
22310
22311/**
22312 * Smooth scroll to named element.
22313 */
22314function smoothScroll(element) {
22315	$('html, body').animate({
22316		scrollTop: $(element).offset().top
22317	}, 500);
22318}
22319var allowSubmit = false;
22320function irtpSubmit() {
22321	allowSubmit = true;
22322	var optOut = 0,
22323		optOutCheckbox = jQuery('#modalIrtpOptOut'),
22324		optOutReason = jQuery('#modalReason'),
22325		formOptOut = jQuery('#irtpOptOut'),
22326		formOptOutReason = jQuery('#irtpOptOutReason');
22327
22328	if (optOutCheckbox.is(':checked')) {
22329		optOut = 1;
22330	}
22331	formOptOut.val(optOut);
22332	formOptOutReason.val(optOutReason.val());
22333	jQuery('#frmDomainContactModification').submit();
22334}
22335
22336function showOverlay(msg) {
22337	jQuery('#fullpage-overlay .msg').html(msg);
22338	jQuery('#fullpage-overlay').show();
22339}
22340
22341function hideOverlay() {
22342	jQuery('#fullpage-overlay').hide();
22343}
22344
22345function getSslAttribute(element, attribute) {
22346	if (element.data(attribute)) {
22347		return element.data(attribute);
22348	}
22349	return element.parent('td').data(attribute);
22350}
22351
22352function removeRetweets() {
22353	jQuery('#twitter-widget-0')
22354		.contents()
22355		.find('.timeline-Tweet--isRetweet')
22356		.parent('li')
22357		.remove();
22358}
22359function addTwitterWidgetObserverWhenNodeAvailable() {
22360	if (elementsWaitTimeout) {
22361		clearTimeout(elementsWaitTimeout);
22362	}
22363
22364	var targetTwitterWidget = document.getElementById('twitter-widget-0');
22365	if (!targetTwitterWidget) {
22366		elementsWaitTimeout = window.setTimeout(addTwitterWidgetObserverWhenNodeAvailable, 500);
22367		return;
22368	}
22369
22370	var targetTimelineTweets = targetTwitterWidget
22371		.contentWindow
22372		.document
22373		.getElementsByClassName('timeline-TweetList')[0];
22374	if (!targetTimelineTweets) {
22375		elementsWaitTimeout = window.setTimeout(addTwitterWidgetObserverWhenNodeAvailable, 500);
22376		return;
22377	}
22378
22379	jQuery('#twitter-widget-0')
22380		.contents()
22381		.find('head')
22382		.append("<style>.timeline-Tweet-text { font-size: 18px !important; line-height: 25px !important; margin-bottom: 0px !important; }</style>");
22383	removeRetweets();
22384	observerTwitterWidget.observe(targetTimelineTweets, observerConfig);
22385}
22386
22387function openValidationSubmitModal(caller)
22388{
22389	var validationSubmitModal = jQuery('#validationSubmitModal');
22390	validationSubmitModal.find('.modal-body iframe').attr('src', caller.dataset.url);
22391	validationSubmitModal.modal('show');
22392}
22393
22394function completeValidationComClientWorkflow()
22395{
22396	var submitDocsRequestBanner = jQuery('.user-validation'),
22397		secondarySidebarStatus = jQuery('.validation-status-label'),
22398		submitDiv = jQuery('.validation-submit-div'),
22399		redirectUser = true;
22400
22401	$('#validationSubmitModal').modal('hide');
22402	if (submitDocsRequestBanner.length !== 0) {
22403		submitDocsRequestBanner.slideUp();
22404		redirectUser = false;
22405	}
22406	if (secondarySidebarStatus.length !== 0) {
22407		var submitString = submitDiv.find('a').data('submitted-string');
22408		secondarySidebarStatus.text(submitString).removeClass('label-default').addClass('label-warning');
22409		submitDiv.hide();
22410		redirectUser = false;
22411	}
22412
22413	if (redirectUser) {
22414		window.location.href = WHMCS.utils.autoDetermineBaseUrl();
22415	}
22416	return false;
22417}
22418
22419var autoCollapse = function (menu, maxHeight) {
22420
22421	var continueLoop = true,
22422		nav = jQuery(menu),
22423		navHeight = nav.innerHeight();
22424	if (navHeight >= maxHeight) {
22425
22426		jQuery(menu + ' .collapsable-dropdown').removeClass('d-none');
22427		jQuery(".navbar-nav").removeClass('w-auto').addClass("w-100");
22428
22429		while (navHeight > maxHeight && continueLoop) {
22430			//  add child to dropdown
22431			var children = nav.children(menu + ' li:not(:last-child):not(".no-collapse")'),
22432				count = children.length;
22433			if (!count) {
22434				continueLoop = false;
22435			} else {
22436				children.data('original-classes', children.attr('class'));
22437				var child = jQuery(children[count - 1]);
22438				child.removeClass().addClass('dropdown-item');
22439				child.prependTo(menu + ' .collapsable-dropdown-menu');
22440			}
22441			navHeight = nav.innerHeight();
22442		}
22443		jQuery(".navbar-nav").addClass("w-auto").removeClass('w-100');
22444
22445	} else {
22446
22447		var collapsed = jQuery(menu + ' .collapsable-dropdown-menu').children(menu + ' li');
22448
22449		if (collapsed.length === 0) {
22450			jQuery(menu + ' .collapsable-dropdown').addClass('d-none');
22451		}
22452
22453		while (navHeight < maxHeight && (nav.children(menu + ' li').length > 0) && collapsed.length > 0) {
22454			//  remove child from dropdown
22455			collapsed = jQuery(menu + ' .collapsable-dropdown-menu').children('li');
22456			var child = jQuery(collapsed[0]);
22457			child.removeClass().addClass(child.data('original-classes'));
22458			child.insertBefore(nav.children(menu + ' li:last-child'));
22459			navHeight = nav.innerHeight();
22460		}
22461
22462		if (navHeight > maxHeight) {
22463			autoCollapse(menu, maxHeight);
22464		}
22465	}
22466}
22467
22468/**
22469 * Perform the AjaxCall for a CustomAction.
22470 *
22471 * @param event
22472 * @param element
22473 * @returns {boolean}
22474 */
22475function customActionAjaxCall(event, element) {
22476	var loadingIcon = jQuery('.loading', element);
22477	var standardIcon = jQuery('.sidebar-menu-item-icon', element);
22478
22479	event.stopPropagation();
22480	if (!element.data('active')) {
22481		return false;
22482	}
22483	element.attr('disabled', 'disabled').addClass('disabled');
22484	loadingIcon.show();
22485	standardIcon.hide();
22486	WHMCS.http.jqClient.jsonPost({
22487		url: WHMCS.utils.getRouteUrl(
22488			'/clientarea/service/' + element.data('serviceid') + '/custom-action/' + element.data('identifier')
22489		),
22490		data: {
22491			'token': csrfToken
22492		},
22493		success: function(data) {
22494			if (data.success) {
22495				window.open(data.redirectTo);
22496			} else {
22497				window.open('clientarea.php?action=productdetails&id=' + element.data('serviceid') + '&customaction_error=1');
22498			}
22499		},
22500		fail: function () {
22501			window.open('clientarea.php?action=productdetails&id=' + element.data('serviceid') + '&customaction_ajax_error=1');
22502		},
22503		always: function() {
22504			loadingIcon.hide();
22505			standardIcon.show();
22506			element.removeAttr('disabled').removeClass('disabled');
22507			if (element.hasClass('dropdown-item')) {
22508				element.closest('.dropdown-menu').removeClass('show');
22509			}
22510		},
22511	});
22512	return true;
22513}
22514
22515/*!
22516 * WHMCS Ajax Driven Modal Framework
22517 *
22518 * @copyright Copyright (c) WHMCS Limited 2005-2021
22519 * @license https://www.whmcs.com/license/ WHMCS Eula
22520 */
22521var ajaxModalSubmitEvents = [],
22522	ajaxModalPostSubmitEvents = [];
22523jQuery(document).ready(function(){
22524	jQuery(document).on('click', '.open-modal', function(e) {
22525		e.preventDefault();
22526		var url = jQuery(this).attr('href'),
22527			modalSize = jQuery(this).data('modal-size'),
22528			modalClass = jQuery(this).data('modal-class'),
22529			modalTitle = jQuery(this).data('modal-title'),
22530			submitId = jQuery(this).data('btn-submit-id'),
22531			submitLabel = jQuery(this).data('btn-submit-label'),
22532			submitColor = jQuery(this).data('btn-submit-color'),
22533			hideClose = jQuery(this).data('btn-close-hide'),
22534			disabled = jQuery(this).attr('disabled'),
22535			successDataTable = jQuery(this).data('datatable-reload-success');
22536
22537		var postData = '';
22538		if (csrfToken) {
22539			postData = {token: csrfToken};
22540		}
22541		if (!disabled) {
22542			openModal(url, postData, modalTitle, modalSize, modalClass, submitLabel, submitId, submitColor, hideClose, successDataTable);
22543		}
22544	});
22545
22546	// define modal close reset action
22547	jQuery('#modalAjax').on('hidden.bs.modal', function (e) {
22548		if (jQuery(this).hasClass('modal-feature-highlights')) {
22549			var dismissForVersion = jQuery('#cbFeatureHighlightsDismissForVersion').is(':checked');
22550			WHMCS.http.jqClient.post(
22551				'whatsnew.php',
22552				{
22553					dismiss: "1",
22554					until_next_update: dismissForVersion ? '1' : '0',
22555					token: csrfToken
22556				}
22557			);
22558		}
22559
22560		jQuery('#modalAjax').find('.modal-body').empty();
22561		jQuery('#modalAjax').children('div.modal-dialog').removeClass('modal-lg');
22562		jQuery('#modalAjax').removeClass().addClass('modal whmcs-modal fade');
22563		jQuery('#modalAjax .modal-title').html('Title');
22564		jQuery('#modalAjax .modal-submit').html('Submit')
22565			.removeClass()
22566			.addClass('btn btn-primary modal-submit')
22567			.removeAttr('id')
22568			.removeAttr('disabled');
22569		jQuery('#modalAjax .loader').show();
22570	});
22571});
22572
22573function openModal(url, postData, modalTitle, modalSize, modalClass, submitLabel, submitId, submitColor, hideClose, successDataTable) {
22574	//set the text of the modal title
22575	jQuery('#modalAjax .modal-title').html(modalTitle);
22576
22577	// set the modal size via a class attribute
22578	if (modalSize) {
22579		jQuery('#modalAjax').children('div[class="modal-dialog"]').addClass(modalSize);
22580	}
22581	// set the modal class
22582	if (modalClass) {
22583		jQuery('#modalAjax').addClass(modalClass);
22584	}
22585
22586	// set the text of the submit button
22587	if(!submitLabel){
22588		jQuery('#modalAjax .modal-submit').hide();
22589	} else {
22590		jQuery('#modalAjax .modal-submit').show().html(submitLabel);
22591		// set the button id so we can target the click function of it.
22592		if (submitId) {
22593			jQuery('#modalAjax .modal-submit').attr('id', submitId);
22594		}
22595	}
22596
22597	if (hideClose) {
22598		jQuery('#modalAjaxClose').hide();
22599	}
22600
22601	if (submitColor) {
22602		jQuery('#modalAjax .modal-submit').removeClass('btn-primary')
22603			.addClass('btn-' + submitColor);
22604	}
22605
22606	jQuery('#modalAjax .modal-body').html('');
22607
22608	jQuery('#modalSkip').hide();
22609	disableSubmit();
22610
22611	// show modal
22612	jQuery('#modalAjax').modal({
22613		show: true,
22614		keyboard: true,
22615		backdrop: jQuery('#modalAjax').hasClass('static') ? 'static' : true
22616	});
22617
22618	// fetch modal content
22619	WHMCS.http.jqClient.post(url, postData, function(data) {
22620		updateAjaxModal(data);
22621	}, 'json').fail(function() {
22622		jQuery('#modalAjax .modal-body').html('An error occurred while communicating with the server. Please try again.');
22623		jQuery('#modalAjax .loader').fadeOut();
22624	}).always(function () {
22625		var modalForm = jQuery('#modalAjax').find('form');
22626		// If a submitId is present, then we're working with a form and need to override the default event
22627		if (submitId) {
22628			modalForm.submit(function (event) {
22629				submitIdAjaxModalClickEvent();
22630				return false;
22631			});
22632		}
22633		if (successDataTable) {
22634			modalForm.data('successDataTable', successDataTable);
22635		}
22636
22637		// Since the content is dynamically fetched, we have to check for the elements we want here too
22638		var inputs = jQuery(modalForm).find('input:not(input[type=checkbox],input[type=radio],input[type=hidden])');
22639
22640		if (inputs.length > 0) {
22641			jQuery(inputs).first().focus();
22642		}
22643	});
22644
22645	//define modal submit button click
22646	if (submitId) {
22647		/**
22648		 * Reloading ajax modal multiple times on the same page can add
22649		 * multiple "on" click events which submits the same form over
22650		 * and over.
22651		 * Remove the on click event with "off" to avoid multiple growl
22652		 * and save events being run.
22653		 *
22654		 * @see http://api.jquery.com/off/
22655		 */
22656		var submitButton = jQuery('#' + submitId);
22657		submitButton.off('click');
22658		submitButton.on('click', submitIdAjaxModalClickEvent);
22659	}
22660}
22661
22662function submitIdAjaxModalClickEvent ()
22663{
22664	var canContinue = true,
22665		loader = jQuery('#modalAjax .loader');
22666	disableSubmit();
22667	loader.show();
22668	if (ajaxModalSubmitEvents.length) {
22669		jQuery.each(ajaxModalSubmitEvents, function (index, value) {
22670			var fn = window[value];
22671			if (canContinue && typeof fn === 'function') {
22672				canContinue = fn();
22673			}
22674		});
22675	}
22676	if (!canContinue) {
22677		enableSubmit();
22678		loader.hide();
22679		return;
22680	}
22681	var modalForm = jQuery('#modalAjax').find('form');
22682	var modalBody = jQuery('#modalAjax .modal-body');
22683	var modalErrorContainer = jQuery(modalBody).find('.admin-modal-error');
22684
22685	jQuery(modalErrorContainer).slideUp();
22686
22687	var modalPost = WHMCS.http.jqClient.post(
22688		modalForm.attr('action'),
22689		modalForm.serialize(),
22690		function(data) {
22691			if (modalForm.data('successDataTable')) {
22692				data.successDataTable = modalForm.data('successDataTable');
22693			}
22694			/**
22695			 * When actions should occur before the ajax modal is updated
22696			 * that do not fall into the standard actions.
22697			 * Calling code (ie the function defined in fn) should validate
22698			 * that the ajax modal being updated is the one that the code should
22699			 * run for, as there is potential for multiple ajax modals on the
22700			 * same page.
22701			 */
22702			if (ajaxModalPostSubmitEvents.length) {
22703				jQuery.each(ajaxModalPostSubmitEvents, function (index, value) {
22704					var fn = window[value];
22705					if (typeof fn === 'function') {
22706						fn(data, modalForm);
22707					}
22708				});
22709			}
22710			updateAjaxModal(data);
22711		},
22712		'json'
22713	).fail(function(xhr) {
22714		var data = xhr.responseJSON;
22715		var genericErrorMsg = 'An error occurred while communicating with the server. Please try again.';
22716		if (data && data.data) {
22717			data = data.data;
22718			if (data.errorMsg) {
22719				if (modalErrorContainer.length > 0) {
22720					jQuery(modalErrorContainer)
22721						.html(data.errorMsg)
22722						.slideDown();
22723				} else {
22724					jQuery.growl.warning({title: data.errorMsgTitle, message: data.errorMsg});
22725				}
22726			} else if (data.data.body) {
22727				jQuery(modalBody).html(data.body);
22728			} else {
22729				jQuery(modalBody).html(genericErrorMsg);
22730			}
22731		} else {
22732			jQuery(modalBody).html(genericErrorMsg);
22733		}
22734		jQuery('#modalAjax .loader').fadeOut();
22735		enableSubmit();
22736	});
22737}
22738
22739function updateAjaxModal(data) {
22740	if (data.reloadPage) {
22741		if (typeof data.reloadPage === 'string') {
22742			window.location = data.reloadPage;
22743		} else {
22744			window.location.reload();
22745		}
22746		return;
22747	}
22748	if (data.successDataTable) {
22749		WHMCS.ui.dataTable.getTableById(data.successDataTable, undefined).ajax.reload();
22750	}
22751	if (data.redirect) {
22752		window.location = data.redirect;
22753	}
22754	if (data.successWindow && typeof window[data.successWindow] === "function") {
22755		window[data.successWindow]();
22756	}
22757	if (data.dismiss) {
22758		dialogClose();
22759	}
22760	if (data.successMsg) {
22761		jQuery.growl.notice({ title: data.successMsgTitle, message: data.successMsg });
22762	}
22763	if (data.errorMsg) {
22764		var inModalErrorContainer = jQuery('#modalAjax .modal-body .admin-modal-error');
22765
22766		if (inModalErrorContainer.length > 0 && !data.dismiss) {
22767			jQuery(inModalErrorContainer)
22768				.html(data.errorMsg)
22769				.slideDown();
22770		} else {
22771			jQuery.growl.warning({title: data.errorMsgTitle, message: data.errorMsg});
22772		}
22773	}
22774	if (data.title) {
22775		jQuery('#modalAjax .modal-title').html(data.title);
22776	}
22777	if (data.body) {
22778		jQuery('#modalAjax .modal-body').html(data.body);
22779	} else {
22780		if (data.url) {
22781			WHMCS.http.jqClient.post(data.url, '', function(data2) {
22782				jQuery('#modalAjax').find('.modal-body').html(data2.body);
22783			}, 'json').fail(function() {
22784				jQuery('#modalAjax').find('.modal-body').html('An error occurred while communicating with the server. Please try again.');
22785				jQuery('#modalAjax').find('.loader').fadeOut();
22786			});
22787		}
22788	}
22789	if (data.submitlabel) {
22790		jQuery('#modalAjax .modal-submit').html(data.submitlabel).show();
22791		if (data.submitId) {
22792			jQuery('#modalAjax').find('.modal-submit').attr('id', data.submitId);
22793		}
22794	}
22795
22796	if (data.submitId) {
22797		/**
22798		 * Reloading ajax modal multiple times on the same page can add
22799		 * multiple "on" click events which submits the same form over
22800		 * and over.
22801		 * Remove the on click event with "off" to avoid multiple growl
22802		 * and save events being run.
22803		 *
22804		 * @see http://api.jquery.com/off/
22805		 */
22806		var submitButton = jQuery('#' + data.submitId);
22807		submitButton.off('click');
22808		submitButton.on('click', submitIdAjaxModalClickEvent);
22809	}
22810
22811	if (data.disableSubmit) {
22812		disableSubmit();
22813	} else {
22814		enableSubmit();
22815	}
22816
22817	var dismissLoader = true;
22818	if (typeof data.dismissLoader !== 'undefined') {
22819		dismissLoader = data.dismissLoader;
22820	}
22821
22822	dismissLoaderAfterRender(dismissLoader);
22823
22824	if (data.hideSubmit) {
22825		ajaxModalHideSubmit();
22826	}
22827}
22828
22829// backwards compat for older dialog implementations
22830
22831function dialogSubmit() {
22832	disableSubmit();
22833	jQuery('#modalAjax .loader').show();
22834	var postUrl = jQuery('#modalAjax').find('form').attr('action');
22835	WHMCS.http.jqClient.post(postUrl, jQuery('#modalAjax').find('form').serialize(),
22836		function(data) {
22837			updateAjaxModal(data);
22838		}, 'json').fail(function() {
22839		jQuery('#modalAjax .modal-body').html('An error occurred while communicating with the server. Please try again.');
22840		jQuery('#modalAjax .loader').fadeOut();
22841	});
22842}
22843
22844function dialogClose() {
22845	jQuery('#modalAjax').modal('hide');
22846}
22847
22848function addAjaxModalSubmitEvents(functionName) {
22849	if (functionName) {
22850		ajaxModalSubmitEvents.push(functionName);
22851	}
22852}
22853
22854function removeAjaxModalSubmitEvents(functionName) {
22855	if (functionName) {
22856		var index = ajaxModalSubmitEvents.indexOf(functionName);
22857		if (index >= 0) {
22858			ajaxModalSubmitEvents.splice(index, 1);
22859		}
22860	}
22861}
22862
22863function addAjaxModalPostSubmitEvents(functionName) {
22864	if (functionName) {
22865		ajaxModalPostSubmitEvents.push(functionName);
22866	}
22867}
22868
22869function removeAjaxModalPostSubmitEvents(functionName) {
22870	if (functionName) {
22871		var index = ajaxModalPostSubmitEvents.indexOf(functionName);
22872		if (index >= 0) {
22873			ajaxModalPostSubmitEvents.splice(index, 1);
22874		}
22875	}
22876}
22877
22878function disableSubmit()
22879{
22880	jQuery('#modalAjax .modal-submit').prop('disabled', true).addClass('disabled');
22881}
22882
22883function enableSubmit()
22884{
22885	jQuery('#modalAjax .modal-submit').prop('disabled', false).removeClass('disabled');
22886}
22887
22888function ajaxModalHideSubmit()
22889{
22890	jQuery('#modalAjax .modal-submit').hide();
22891}
22892
22893function dismissLoaderAfterRender(showLoader)
22894{
22895	if (showLoader === false) {
22896		jQuery('#modalAjax .loader').show();
22897	} else {
22898		jQuery('#modalAjax .loader').fadeOut();
22899	}
22900}
22901
22902/**
22903 * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.
22904 *
22905 * @version v4.0.0-alpha.1
22906 * @homepage http://www.bootstrap-switch.org
22907 * @author Mattia Larentis <[email protected]> (http://larentis.eu)
22908 * @license Apache-2.0
22909 */
22910
22911'use strict';
22912
22913var _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; }; }();
22914
22915function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22916
22917(function ($, window) {
22918	var BootstrapSwitch = function () {
22919		function BootstrapSwitch(element) {
22920			var _this = this;
22921
22922			var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
22923
22924			_classCallCheck(this, BootstrapSwitch);
22925
22926			this.$element = $(element);
22927			this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, this._getElementOptions(), options);
22928			this.prevOptions = {};
22929			this.$wrapper = $('<div>', {
22930				class: function _class() {
22931					var classes = [];
22932					classes.push(_this.options.state ? 'on' : 'off');
22933					if (_this.options.size) {
22934						classes.push(_this.options.size);
22935					}
22936					if (_this.options.disabled) {
22937						classes.push('disabled');
22938					}
22939					if (_this.options.readonly) {
22940						classes.push('readonly');
22941					}
22942					if (_this.options.indeterminate) {
22943						classes.push('indeterminate');
22944					}
22945					if (_this.options.inverse) {
22946						classes.push('inverse');
22947					}
22948					if (_this.$element.attr('id')) {
22949						classes.push('id-' + _this.$element.attr('id'));
22950					}
22951					return classes.map(_this._getClass.bind(_this)).concat([_this.options.baseClass], _this._getClasses(_this.options.wrapperClass)).join(' ');
22952				}
22953			});
22954			this.$container = $('<div>', { class: this._getClass('container') });
22955			this.$on = $('<span>', {
22956				html: this.options.onText,
22957				class: this._getClass('handle-on') + ' ' + this._getClass(this.options.onColor)
22958			});
22959			this.$off = $('<span>', {
22960				html: this.options.offText,
22961				class: this._getClass('handle-off') + ' ' + this._getClass(this.options.offColor)
22962			});
22963			this.$label = $('<span>', {
22964				html: this.options.labelText,
22965				class: this._getClass('label')
22966			});
22967
22968			this.$element.on('init.bootstrapSwitch', this.options.onInit.bind(this, element));
22969			this.$element.on('switchChange.bootstrapSwitch', function () {
22970				for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
22971					args[_key] = arguments[_key];
22972				}
22973
22974				if (_this.options.onSwitchChange.apply(element, args) === false) {
22975					if (_this.$element.is(':radio')) {
22976						$('[name="' + _this.$element.attr('name') + '"]').trigger('previousState.bootstrapSwitch', true);
22977					} else {
22978						_this.$element.trigger('previousState.bootstrapSwitch', true);
22979					}
22980				}
22981			});
22982
22983			this.$container = this.$element.wrap(this.$container).parent();
22984			this.$wrapper = this.$container.wrap(this.$wrapper).parent();
22985			this.$element.before(this.options.inverse ? this.$off : this.$on).before(this.$label).before(this.options.inverse ? this.$on : this.$off);
22986
22987			if (this.options.indeterminate) {
22988				this.$element.prop('indeterminate', true);
22989			}
22990
22991			this._init();
22992			this._elementHandlers();
22993			this._handleHandlers();
22994			this._labelHandlers();
22995			this._formHandler();
22996			this._externalLabelHandler();
22997			this.$element.trigger('init.bootstrapSwitch', this.options.state);
22998		}
22999
23000		_createClass(BootstrapSwitch, [{
23001			key: 'setPrevOptions',
23002			value: function setPrevOptions() {
23003				this.prevOptions = Object.assign({}, this.options);
23004			}
23005		}, {
23006			key: 'state',
23007			value: function state(value, skip) {
23008				if (typeof value === 'undefined') {
23009					return this.options.state;
23010				}
23011				if (this.options.disabled || this.options.readonly || this.options.state && !this.options.radioAllOff && this.$element.is(':radio')) {
23012					return this.$element;
23013				}
23014				if (this.$element.is(':radio')) {
23015					$('[name="' + this.$element.attr('name') + '"]').trigger('setPreviousOptions.bootstrapSwitch');
23016				} else {
23017					this.$element.trigger('setPreviousOptions.bootstrapSwitch');
23018				}
23019				if (this.options.indeterminate) {
23020					this.indeterminate(false);
23021				}
23022				this.$element.prop('checked', Boolean(value)).trigger('change.bootstrapSwitch', skip);
23023				return this.$element;
23024			}
23025		}, {
23026			key: 'toggleState',
23027			value: function toggleState(skip) {
23028				if (this.options.disabled || this.options.readonly) {
23029					return this.$element;
23030				}
23031				if (this.options.indeterminate) {
23032					this.indeterminate(false);
23033					return this.state(true);
23034				} else {
23035					return this.$element.prop('checked', !this.options.state).trigger('change.bootstrapSwitch', skip);
23036				}
23037			}
23038		}, {
23039			key: 'size',
23040			value: function size(value) {
23041				if (typeof value === 'undefined') {
23042					return this.options.size;
23043				}
23044				if (this.options.size != null) {
23045					this.$wrapper.removeClass(this._getClass(this.options.size));
23046				}
23047				if (value) {
23048					this.$wrapper.addClass(this._getClass(value));
23049				}
23050				this._width();
23051				this._containerPosition();
23052				this.options.size = value;
23053				return this.$element;
23054			}
23055		}, {
23056			key: 'animate',
23057			value: function animate(value) {
23058				if (typeof value === 'undefined') {
23059					return this.options.animate;
23060				}
23061				if (this.options.animate === Boolean(value)) {
23062					return this.$element;
23063				}
23064				return this.toggleAnimate();
23065			}
23066		}, {
23067			key: 'toggleAnimate',
23068			value: function toggleAnimate() {
23069				this.options.animate = !this.options.animate;
23070				this.$wrapper.toggleClass(this._getClass('animate'));
23071				return this.$element;
23072			}
23073		}, {
23074			key: 'disabled',
23075			value: function disabled(value) {
23076				if (typeof value === 'undefined') {
23077					return this.options.disabled;
23078				}
23079				if (this.options.disabled === Boolean(value)) {
23080					return this.$element;
23081				}
23082				return this.toggleDisabled();
23083			}
23084		}, {
23085			key: 'toggleDisabled',
23086			value: function toggleDisabled() {
23087				this.options.disabled = !this.options.disabled;
23088				this.$element.prop('disabled', this.options.disabled);
23089				this.$wrapper.toggleClass(this._getClass('disabled'));
23090				return this.$element;
23091			}
23092		}, {
23093			key: 'readonly',
23094			value: function readonly(value) {
23095				if (typeof value === 'undefined') {
23096					return this.options.readonly;
23097				}
23098				if (this.options.readonly === Boolean(value)) {
23099					return this.$element;
23100				}
23101				return this.toggleReadonly();
23102			}
23103		}, {
23104			key: 'toggleReadonly',
23105			value: function toggleReadonly() {
23106				this.options.readonly = !this.options.readonly;
23107				this.$element.prop('readonly', this.options.readonly);
23108				this.$wrapper.toggleClass(this._getClass('readonly'));
23109				return this.$element;
23110			}
23111		}, {
23112			key: 'indeterminate',
23113			value: function indeterminate(value) {
23114				if (typeof value === 'undefined') {
23115					return this.options.indeterminate;
23116				}
23117				if (this.options.indeterminate === Boolean(value)) {
23118					return this.$element;
23119				}
23120				return this.toggleIndeterminate();
23121			}
23122		}, {
23123			key: 'toggleIndeterminate',
23124			value: function toggleIndeterminate() {
23125				this.options.indeterminate = !this.options.indeterminate;
23126				this.$element.prop('indeterminate', this.options.indeterminate);
23127				this.$wrapper.toggleClass(this._getClass('indeterminate'));
23128				this._containerPosition();
23129				return this.$element;
23130			}
23131		}, {
23132			key: 'inverse',
23133			value: function inverse(value) {
23134				if (typeof value === 'undefined') {
23135					return this.options.inverse;
23136				}
23137				if (this.options.inverse === Boolean(value)) {
23138					return this.$element;
23139				}
23140				return this.toggleInverse();
23141			}
23142		}, {
23143			key: 'toggleInverse',
23144			value: function toggleInverse() {
23145				this.$wrapper.toggleClass(this._getClass('inverse'));
23146				var $on = this.$on.clone(true);
23147				var $off = this.$off.clone(true);
23148				this.$on.replaceWith($off);
23149				this.$off.replaceWith($on);
23150				this.$on = $off;
23151				this.$off = $on;
23152				this.options.inverse = !this.options.inverse;
23153				return this.$element;
23154			}
23155		}, {
23156			key: 'onColor',
23157			value: function onColor(value) {
23158				if (typeof value === 'undefined') {
23159					return this.options.onColor;
23160				}
23161				if (this.options.onColor) {
23162					this.$on.removeClass(this._getClass(this.options.onColor));
23163				}
23164				this.$on.addClass(this._getClass(value));
23165				this.options.onColor = value;
23166				return this.$element;
23167			}
23168		}, {
23169			key: 'offColor',
23170			value: function offColor(value) {
23171				if (typeof value === 'undefined') {
23172					return this.options.offColor;
23173				}
23174				if (this.options.offColor) {
23175					this.$off.removeClass(this._getClass(this.options.offColor));
23176				}
23177				this.$off.addClass(this._getClass(value));
23178				this.options.offColor = value;
23179				return this.$element;
23180			}
23181		}, {
23182			key: 'onText',
23183			value: function onText(value) {
23184				if (typeof value === 'undefined') {
23185					return this.options.onText;
23186				}
23187				this.$on.html(value);
23188				this._width();
23189				this._containerPosition();
23190				this.options.onText = value;
23191				return this.$element;
23192			}
23193		}, {
23194			key: 'offText',
23195			value: function offText(value) {
23196				if (typeof value === 'undefined') {
23197					return this.options.offText;
23198				}
23199				this.$off.html(value);
23200				this._width();
23201				this._containerPosition();
23202				this.options.offText = value;
23203				return this.$element;
23204			}
23205		}, {
23206			key: 'labelText',
23207			value: function labelText(value) {
23208				if (typeof value === 'undefined') {
23209					return this.options.labelText;
23210				}
23211				this.$label.html(value);
23212				this._width();
23213				this.options.labelText = value;
23214				return this.$element;
23215			}
23216		}, {
23217			key: 'handleWidth',
23218			value: function handleWidth(value) {
23219				if (typeof value === 'undefined') {
23220					return this.options.handleWidth;
23221				}
23222				this.options.handleWidth = value;
23223				this._width();
23224				this._containerPosition();
23225				return this.$element;
23226			}
23227		}, {
23228			key: 'labelWidth',
23229			value: function labelWidth(value) {
23230				if (typeof value === 'undefined') {
23231					return this.options.labelWidth;
23232				}
23233				this.options.labelWidth = value;
23234				this._width();
23235				this._containerPosition();
23236				return this.$element;
23237			}
23238		}, {
23239			key: 'baseClass',
23240			value: function baseClass(value) {
23241				return this.options.baseClass;
23242			}
23243		}, {
23244			key: 'wrapperClass',
23245			value: function wrapperClass(value) {
23246				if (typeof value === 'undefined') {
23247					return this.options.wrapperClass;
23248				}
23249				if (!value) {
23250					value = $.fn.bootstrapSwitch.defaults.wrapperClass;
23251				}
23252				this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(' '));
23253				this.$wrapper.addClass(this._getClasses(value).join(' '));
23254				this.options.wrapperClass = value;
23255				return this.$element;
23256			}
23257		}, {
23258			key: 'radioAllOff',
23259			value: function radioAllOff(value) {
23260				if (typeof value === 'undefined') {
23261					return this.options.radioAllOff;
23262				}
23263				var val = Boolean(value);
23264				if (this.options.radioAllOff === val) {
23265					return this.$element;
23266				}
23267				this.options.radioAllOff = val;
23268				return this.$element;
23269			}
23270		}, {
23271			key: 'onInit',
23272			value: function onInit(value) {
23273				if (typeof value === 'undefined') {
23274					return this.options.onInit;
23275				}
23276				if (!value) {
23277					value = $.fn.bootstrapSwitch.defaults.onInit;
23278				}
23279				this.options.onInit = value;
23280				return this.$element;
23281			}
23282		}, {
23283			key: 'onSwitchChange',
23284			value: function onSwitchChange(value) {
23285				if (typeof value === 'undefined') {
23286					return this.options.onSwitchChange;
23287				}
23288				if (!value) {
23289					value = $.fn.bootstrapSwitch.defaults.onSwitchChange;
23290				}
23291				this.options.onSwitchChange = value;
23292				return this.$element;
23293			}
23294		}, {
23295			key: 'destroy',
23296			value: function destroy() {
23297				var $form = this.$element.closest('form');
23298				if ($form.length) {
23299					$form.off('reset.bootstrapSwitch').removeData('bootstrap-switch');
23300				}
23301				this.$container.children().not(this.$element).remove();
23302				this.$element.unwrap().unwrap().off('.bootstrapSwitch').removeData('bootstrap-switch');
23303				return this.$element;
23304			}
23305		}, {
23306			key: '_getElementOptions',
23307			value: function _getElementOptions() {
23308				return {
23309					state: this.$element.is(':checked'),
23310					size: this.$element.data('size'),
23311					animate: this.$element.data('animate'),
23312					disabled: this.$element.is(':disabled'),
23313					readonly: this.$element.is('[readonly]'),
23314					indeterminate: this.$element.data('indeterminate'),
23315					inverse: this.$element.data('inverse'),
23316					radioAllOff: this.$element.data('radio-all-off'),
23317					onColor: this.$element.data('on-color'),
23318					offColor: this.$element.data('off-color'),
23319					onText: this.$element.data('on-text'),
23320					offText: this.$element.data('off-text'),
23321					labelText: this.$element.data('label-text'),
23322					handleWidth: this.$element.data('handle-width'),
23323					labelWidth: this.$element.data('label-width'),
23324					baseClass: this.$element.data('base-class'),
23325					wrapperClass: this.$element.data('wrapper-class')
23326				};
23327			}
23328		}, {
23329			key: '_width',
23330			value: function _width() {
23331				var _this2 = this;
23332
23333				var $handles = this.$on.add(this.$off).add(this.$label).css('width', '');
23334				var handleWidth = void 0;
23335				if (this.options.handleWidth === 'auto') {
23336					handleWidth = Math.round(Math.max(this.$on.width(), this.$off.width()));
23337				} else {
23338					handleWidth = this.options.handleWidth;
23339				}
23340				$handles.width(handleWidth);
23341				this.$label.width(function (index, width) {
23342					if (_this2.options.labelWidth !== 'auto') {
23343						return _this2.options.labelWidth;
23344					}
23345					if (width < handleWidth) {
23346						return handleWidth;
23347					}
23348					return width;
23349				});
23350				this._handleWidth = this.$on.outerWidth();
23351				this._labelWidth = this.$label.outerWidth();
23352				this.$container.width(this._handleWidth * 2 + this._labelWidth);
23353				return this.$wrapper.width(this._handleWidth + this._labelWidth);
23354			}
23355		}, {
23356			key: '_containerPosition',
23357			value: function _containerPosition() {
23358				var _this3 = this;
23359
23360				var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.state;
23361				var callback = arguments[1];
23362
23363				this.$container.css('margin-left', function () {
23364					var values = [0, '-' + _this3._handleWidth + 'px'];
23365					if (_this3.options.indeterminate) {
23366						return '-' + _this3._handleWidth / 2 + 'px';
23367					}
23368					if (state) {
23369						if (_this3.options.inverse) {
23370							return values[1];
23371						} else {
23372							return values[0];
23373						}
23374					} else {
23375						if (_this3.options.inverse) {
23376							return values[0];
23377						} else {
23378							return values[1];
23379						}
23380					}
23381				});
23382			}
23383		}, {
23384			key: '_init',
23385			value: function _init() {
23386				var _this4 = this;
23387
23388				var init = function init() {
23389					_this4.setPrevOptions();
23390					_this4._width();
23391					_this4._containerPosition();
23392					setTimeout(function () {
23393						if (_this4.options.animate) {
23394							return _this4.$wrapper.addClass(_this4._getClass('animate'));
23395						}
23396					}, 50);
23397				};
23398				if (this.$wrapper.is(':visible')) {
23399					init();
23400					return;
23401				}
23402				var initInterval = window.setInterval(function () {
23403					if (_this4.$wrapper.is(':visible')) {
23404						init();
23405						return window.clearInterval(initInterval);
23406					}
23407				}, 50);
23408			}
23409		}, {
23410			key: '_elementHandlers',
23411			value: function _elementHandlers() {
23412				var _this5 = this;
23413
23414				return this.$element.on({
23415					'setPreviousOptions.bootstrapSwitch': this.setPrevOptions.bind(this),
23416
23417					'previousState.bootstrapSwitch': function previousStateBootstrapSwitch() {
23418						_this5.options = _this5.prevOptions;
23419						if (_this5.options.indeterminate) {
23420							_this5.$wrapper.addClass(_this5._getClass('indeterminate'));
23421						}
23422						_this5.$element.prop('checked', _this5.options.state).trigger('change.bootstrapSwitch', true);
23423					},
23424
23425					'change.bootstrapSwitch': function changeBootstrapSwitch(event, skip) {
23426						event.preventDefault();
23427						event.stopImmediatePropagation();
23428						var state = _this5.$element.is(':checked');
23429						_this5._containerPosition(state);
23430						if (state === _this5.options.state) {
23431							return;
23432						}
23433						_this5.options.state = state;
23434						_this5.$wrapper.toggleClass(_this5._getClass('off')).toggleClass(_this5._getClass('on'));
23435						if (!skip) {
23436							if (_this5.$element.is(':radio')) {
23437								$('[name="' + _this5.$element.attr('name') + '"]').not(_this5.$element).prop('checked', false).trigger('change.bootstrapSwitch', true);
23438							}
23439							_this5.$element.trigger('switchChange.bootstrapSwitch', [state]);
23440						}
23441					},
23442
23443					'focus.bootstrapSwitch': function focusBootstrapSwitch(event) {
23444						event.preventDefault();
23445						_this5.$wrapper.addClass(_this5._getClass('focused'));
23446					},
23447
23448					'blur.bootstrapSwitch': function blurBootstrapSwitch(event) {
23449						event.preventDefault();
23450						_this5.$wrapper.removeClass(_this5._getClass('focused'));
23451					},
23452
23453					'keydown.bootstrapSwitch': function keydownBootstrapSwitch(event) {
23454						if (!event.which || _this5.options.disabled || _this5.options.readonly) {
23455							return;
23456						}
23457						if (event.which === 37 || event.which === 39) {
23458							event.preventDefault();
23459							event.stopImmediatePropagation();
23460							_this5.state(event.which === 39);
23461						}
23462					}
23463				});
23464			}
23465		}, {
23466			key: '_handleHandlers',
23467			value: function _handleHandlers() {
23468				var _this6 = this;
23469
23470				this.$on.on('click.bootstrapSwitch', function (event) {
23471					event.preventDefault();
23472					event.stopPropagation();
23473					_this6.state(false);
23474					return _this6.$element.trigger('focus.bootstrapSwitch');
23475				});
23476				return this.$off.on('click.bootstrapSwitch', function (event) {
23477					event.preventDefault();
23478					event.stopPropagation();
23479					_this6.state(true);
23480					return _this6.$element.trigger('focus.bootstrapSwitch');
23481				});
23482			}
23483		}, {
23484			key: '_labelHandlers',
23485			value: function _labelHandlers() {
23486				var _this7 = this;
23487
23488				var handlers = {
23489					click: function click(event) {
23490						event.stopPropagation();
23491					},
23492
23493
23494					'mousedown.bootstrapSwitch touchstart.bootstrapSwitch': function mousedownBo
23494otstrapSwitchTouchstartBootstrapSwitch(event) {
23495						if (_this7._dragStart || _this7.options.disabled || _this7.options.readonly) {
23496							return;
23497						}
23498						event.preventDefault();
23499						event.stopPropagation();
23500						_this7._dragStart = (event.pageX || event.originalEvent.touches[0].pageX) - parseInt(_this7.$container.css('margin-left'), 10);
23501						if (_this7.options.animate) {
23502							_this7.$wrapper.removeClass(_this7._getClass('animate'));
23503						}
23504						_this7.$element.trigger('focus.bootstrapSwitch');
23505					},
23506
23507					'mousemove.bootstrapSwitch touchmove.bootstrapSwitch': function mousemoveBootstrapSwitchTouchmoveBootstrapSwitch(event) {
23508						if (_this7._dragStart == null) {
23509							return;
23510						}
23511						var difference = (event.pageX || event.originalEvent.touches[0].pageX) - _this7._dragStart;
23512						event.preventDefault();
23513						if (difference < -_this7._handleWidth || difference > 0) {
23514							return;
23515						}
23516						_this7._dragEnd = difference;
23517						_this7.$container.css('margin-left', _this7._dragEnd + 'px');
23518					},
23519
23520					'mouseup.bootstrapSwitch touchend.bootstrapSwitch': function mouseupBootstrapSwitchTouchendBootstrapSwitch(event) {
23521						if (!_this7._dragStart) {
23522							return;
23523						}
23524						event.preventDefault();
23525						if (_this7.options.animate) {
23526							_this7.$wrapper.addClass(_this7._getClass('animate'));
23527						}
23528						if (_this7._dragEnd) {
23529							var state = _this7._dragEnd > -(_this7._handleWidth / 2);
23530							_this7._dragEnd = false;
23531							_this7.state(_this7.options.inverse ? !state : state);
23532						} else {
23533							_this7.state(!_this7.options.state);
23534						}
23535						_this7._dragStart = false;
23536					},
23537
23538					'mouseleave.bootstrapSwitch': function mouseleaveBootstrapSwitch() {
23539						_this7.$label.trigger('mouseup.bootstrapSwitch');
23540					}
23541				};
23542				this.$label.on(handlers);
23543			}
23544		}, {
23545			key: '_externalLabelHandler',
23546			value: function _externalLabelHandler() {
23547				var _this8 = this;
23548
23549				var $externalLabel = this.$element.closest('label');
23550				$externalLabel.on('click', function (event) {
23551					event.preventDefault();
23552					event.stopImmediatePropagation();
23553					if (event.target === $externalLabel[0]) {
23554						_this8.toggleState();
23555					}
23556				});
23557			}
23558		}, {
23559			key: '_formHandler',
23560			value: function _formHandler() {
23561				var $form = this.$element.closest('form');
23562				if ($form.data('bootstrap-switch')) {
23563					return;
23564				}
23565				$form.on('reset.bootstrapSwitch', function () {
23566					window.setTimeout(function () {
23567						$form.find('input').filter(function () {
23568							return $(this).data('bootstrap-switch');
23569						}).each(function () {
23570							return $(this).bootstrapSwitch('state', this.checked);
23571						});
23572					}, 1);
23573				}).data('bootstrap-switch', true);
23574			}
23575		}, {
23576			key: '_getClass',
23577			value: function _getClass(name) {
23578				return this.options.baseClass + '-' + name;
23579			}
23580		}, {
23581			key: '_getClasses',
23582			value: function _getClasses(classes) {
23583				if (!$.isArray(classes)) {
23584					return [this._getClass(classes)];
23585				}
23586				return classes.map(this._getClass.bind(this));
23587			}
23588		}]);
23589
23590		return BootstrapSwitch;
23591	}();
23592
23593	$.fn.bootstrapSwitch = function (option) {
23594		for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
23595			args[_key2 - 1] = arguments[_key2];
23596		}
23597
23598		var ret = this;
23599		this.each(function () {
23600			var $this = $(this);
23601			var data = $this.data('bootstrap-switch');
23602			if (!data) {
23603				data = new BootstrapSwitch(this, option);
23604				$this.data('bootstrap-switch', data);
23605			}
23606			if (typeof option === 'string') {
23607				ret = data[option].apply(data, args);
23608			}
23609		});
23610		return ret;
23611	};
23612	$.fn.bootstrapSwitch.Constructor = BootstrapSwitch;
23613	$.fn.bootstrapSwitch.defaults = {
23614		state: true,
23615		size: null,
23616		animate: true,
23617		disabled: false,
23618		readonly: false,
23619		indeterminate: false,
23620		inverse: false,
23621		radioAllOff: false,
23622		onColor: 'primary',
23623		offColor: 'secondary',
23624		onText: 'ON',
23625		offText: 'OFF',
23626		labelText: '&nbsp',
23627		handleWidth: 'auto',
23628		labelWidth: 'auto',
23629		baseClass: 'bootstrap-switch',
23630		wrapperClass: 'wrapper',
23631		onInit: function onInit() {},
23632		onSwitchChange: function onSwitchChange() {}
23633	};
23634})(window.jQuery, window);
23635
23636/* ===================================================
23637 * bootstrap-markdown.js v2.10.0
23638 * http://github.com/toopay/bootstrap-markdown
23639 * ===================================================
23640 * Copyright 2013-2016 Taufan Aditya
23641 *
23642 * Licensed under the Apache License, Version 2.0 (the "License");
23643 * you may not use this file except in compliance with the License.
23644 * You may obtain a copy of the License at
23645 *
23646 * http://www.apache.org/licenses/LICENSE-2.0
23647 *
23648 * Unless required by applicable law or agreed to in writing, software
23649 * distributed under the License is distributed on an "AS IS" BASIS,
23650 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23651 * See the License for the specific language governing permissions and
23652 * limitations under the License.
23653 * ========================================================== */
23654(function(factory) {
23655	if (typeof define === "function" && define.amd) {
23656		// RequireJS
23657		define(["jquery"], factory);
23658	} else if (typeof exports === 'object') {
23659		// Backbone.js
23660		factory(require('jquery'));
23661	} else {
23662		// jQuery plugin
23663		factory(jQuery);
23664	}
23665}(function($) {
23666	"use strict";
23667
23668	/* MARKDOWN CLASS DEFINITION
23669   * ========================== */
23670
23671	var Markdown = function(element, options) {
23672		// @TODO : remove this BC on next major release
23673		// @see : https://github.com/toopay/bootstrap-markdown/issues/109
23674		var opts = ['autofocus', 'savable', 'hideable', 'width',
23675			'height', 'resize', 'iconlibrary', 'language',
23676			'footer', 'fullscreen', 'hiddenButtons', 'disabledButtons'
23677		];
23678		$.each(opts, function(_, opt) {
23679			if (typeof $(element).data(opt) !== 'undefined') {
23680				options = typeof options == 'object' ? options : {};
23681				options[opt] = $(element).data(opt);
23682			}
23683		});
23684		// End BC
23685
23686		// Class Properties
23687		this.$ns = 'bootstrap-markdown';
23688		this.$element = $(element);
23689		this.$editable = {
23690			el: null,
23691			type: null,
23692			attrKeys: [],
23693			attrValues: [],
23694			content: null
23695		};
23696		this.$options = $.extend(true, {}, $.fn.markdown.defaults, options, this.$element.data('options'));
23697		this.$oldContent = null;
23698		this.$isPreview = false;
23699		this.$isFullscreen = false;
23700		this.$editor = null;
23701		this.$textarea = null;
23702		this.$handler = [];
23703		this.$callback = [];
23704		this.$nextTab = [];
23705
23706		this.showEditor();
23707	};
23708
23709	Markdown.prototype = {
23710
23711		constructor: Markdown,
23712		__alterButtons: function(name, alter) {
23713			var handler = this.$handler,
23714				isAll = (name == 'all'),
23715				that = this;
23716
23717			$.each(handler, function(k, v) {
23718				var halt = true;
23719				if (isAll) {
23720					halt = false;
23721				} else {
23722					halt = v.indexOf(name) < 0;
23723				}
23724
23725				if (halt === false) {
23726					alter(that.$editor.find('button[data-handler="' + v + '"]'));
23727				}
23728			});
23729		},
23730		__buildButtons: function(buttonsArray, container) {
23731			var i,
23732				ns = this.$ns,
23733				handler = this.$handler,
23734				callback = this.$callback;
23735
23736			for (i = 0; i < buttonsArray.length; i++) {
23737				// Build each group container
23738				var y, btnGroups = buttonsArray[i];
23739				for (y = 0; y < btnGroups.length; y++) {
23740					// Build each button group
23741					var z,
23742						buttons = btnGroups[y].data,
23743						btnGroupContainer = $('<div/>', {
23744							'class': 'btn-group'
23745						});
23746
23747					for (z = 0; z < buttons.length; z++) {
23748						var button = buttons[z],
23749							buttonContainer, buttonIconContainer,
23750							buttonHandler = ns + '-' + button.name,
23751							buttonIcon = this.__getIcon(button),
23752							btnText = button.btnText ? button.btnText : '',
23753							btnClass = button.btnClass ? button.btnClass : 'btn',
23754							tabIndex = button.tabIndex ? button.tabIndex : '-1',
23755							hotkey = typeof button.hotkey !== 'undefined' ? button.hotkey : '',
23756							hotkeyCaption = typeof jQuery.hotkeys !== 'undefined' && hotkey !== '' ? ' (' + hotkey + ')' : '';
23757
23758						// Construct the button object
23759						buttonContainer = $('<button></button>');
23760						buttonContainer.text(' ' + this.__localize(btnText)).addClass('btn-default btn-sm').addClass(btnClass);
23761						if (btnClass.match(/btn\-(primary|success|info|warning|danger|link)/)) {
23762							buttonContainer.removeClass('btn-default');
23763						}
23764						buttonContainer.attr({
23765							'type': 'button',
23766							'title': this.__localize(button.title) + hotkeyCaption,
23767							'tabindex': tabIndex,
23768							'data-provider': ns,
23769							'data-handler': buttonHandler,
23770							'data-hotkey': hotkey
23771						});
23772						if (button.toggle === true) {
23773							buttonContainer.attr('data-toggle', 'button');
23774						}
23775						buttonIconContainer = $('<span/>');
23776						buttonIconContainer.addClass(buttonIcon);
23777						buttonIconContainer.prependTo(buttonContainer);
23778
23779						// Attach the button object
23780						btnGroupContainer.append(buttonContainer);
23781
23782						// Register handler and callback
23783						handler.push(buttonHandler);
23784						callback.push(button.callback);
23785					}
23786
23787					// Attach the button group into container DOM
23788					container.append(btnGroupContainer);
23789				}
23790			}
23791
23792			return container;
23793		},
23794		__setListener: function() {
23795			// Set size and resizable Properties
23796			var hasRows = typeof this.$textarea.attr('rows') !== 'undefined',
23797				maxRows = this.$textarea.val().split("\n").length > 5 ? this.$textarea.val().split("\n").length : '5',
23798				rowsVal = hasRows ? this.$textarea.attr('rows') : maxRows;
23799
23800			this.$textarea.attr('rows', rowsVal);
23801			if (this.$options.resize) {
23802				this.$textarea.css('resize', this.$options.resize);
23803			}
23804
23805			// Re-attach markdown data
23806			this.$textarea.data('markdown', this);
23807		},
23808		__setEventListeners: function() {
23809			this.$textarea.on({
23810				'focus': $.proxy(this.focus, this),
23811				'keyup': $.proxy(this.keyup, this),
23812				'change': $.proxy(this.change, this),
23813				'select': $.proxy(this.select, this)
23814			});
23815
23816			if (this.eventSupported('keydown')) {
23817				this.$textarea.on('keydown', $.proxy(this.keydown, this));
23818			}
23819
23820			if (this.eventSupported('keypress')) {
23821				this.$textarea.on('keypress', $.proxy(this.keypress, this));
23822			}
23823		},
23824		__handle: function(e) {
23825			var target = $(e.currentTarget),
23826				handler = this.$handler,
23827				callback = this.$callback,
23828				handlerName = target.attr('data-handler'),
23829				callbackIndex = handler.indexOf(handlerName),
23830				callbackHandler = callback[callbackIndex];
23831
23832			// Trigger the focusin
23833			$(e.currentTarget).focus();
23834
23835			callbackHandler(this);
23836
23837			// Trigger onChange for each button handle
23838			this.change(this);
23839
23840			// Unless it was the save handler,
23841			// focusin the textarea
23842			if (handlerName.indexOf('cmdSave') < 0) {
23843				this.$textarea.focus();
23844			}
23845
23846			e.preventDefault();
23847		},
23848		__localize: function(string) {
23849			var messages = $.fn.markdown.messages,
23850				language = this.$options.language;
23851			if (
23852				typeof messages !== 'undefined' &&
23853				typeof messages[language] !== 'undefined' &&
23854				typeof messages[language][string] !== 'undefined'
23855			) {
23856				return messages[language][string];
23857			}
23858			return string;
23859		},
23860		__getIcon: function(src) {
23861			if(typeof src == 'object'){
23862				var customIcon = this.$options.customIcons[src.name];
23863				return typeof customIcon == 'undefined' ? src.icon[this.$options.iconlibrary] : customIcon;
23864			} else {
23865				return src;
23866			}
23867		},
23868		setFullscreen: function(mode) {
23869			var $editor = this.$editor,
23870				$textarea = this.$textarea;
23871
23872			if (mode === true) {
23873				$editor.addClass('md-fullscreen-mode');
23874				$('body').addClass('md-nooverflow');
23875				this.$options.onFullscreen(this);
23876			} else {
23877				$editor.removeClass('md-fullscreen-mode');
23878				$('body').removeClass('md-nooverflow');
23879				this.$options.onFullscreenExit(this);
23880
23881				if (this.$isPreview === true)
23882					this.hidePreview().showPreview();
23883			}
23884
23885			this.$isFullscreen = mode;
23886			$textarea.focus();
23887		},
23888		showEditor: function() {
23889			var instance = this,
23890				textarea,
23891				ns = this.$ns,
23892				container = this.$element,
23893				originalHeigth = container.css('height'),
23894				originalWidth = container.css('width'),
23895				editable = this.$editable,
23896				handler = this.$handler,
23897				callback = this.$callback,
23898				options = this.$options,
23899				editor = $('<div/>', {
23900					'class': 'md-editor',
23901					click: function() {
23902						instance.focus();
23903					}
23904				});
23905
23906			// Prepare the editor
23907			if (this.$editor === null) {
23908				// Create the panel
23909				var editorHeader = $('<div/>', {
23910					'class': 'md-header btn-toolbar'
23911				});
23912
23913				// Merge the main & additional button groups together
23914				var allBtnGroups = [];
23915				if (options.buttons.length > 0) allBtnGroups = allBtnGroups.concat(options.buttons[0]);
23916				if (options.additionalButtons.length > 0) {
23917					// iterate the additional button groups
23918					$.each(options.additionalButtons[0], function(idx, buttonGroup) {
23919
23920						// see if the group name of the additional group matches an existing group
23921						var matchingGroups = $.grep(allBtnGroups, function(allButtonGroup, allIdx) {
23922							return allButtonGroup.name === buttonGroup.name;
23923						});
23924
23925						// if it matches add the additional buttons to that group, if not just add it to the all buttons group
23926						if (matchingGroups.length > 0) {
23927							matchingGroups[0].data = matchingGroups[0].data.concat(buttonGroup.data);
23928						} else {
23929							allBtnGroups.push(options.additionalButtons[0][idx]);
23930						}
23931
23932					});
23933				}
23934
23935				// Reduce and/or reorder the button groups
23936				if (options.reorderButtonGroups.length > 0) {
23937					allBtnGroups = allBtnGroups
23938						.filter(function(btnGroup) {
23939							return options.reorderButtonGroups.indexOf(btnGroup.name) > -1;
23940						})
23941						.sort(function(a, b) {
23942							if (options.reorderButtonGroups.indexOf(a.name) < options.reorderButtonGroups.indexOf(b.name)) return -1;
23943							if (options.reorderButtonGroups.indexOf(a.name) > options.reorderButtonGroups.indexOf(b.name)) return 1;
23944							return 0;
23945						});
23946				}
23947
23948				// Build the buttons
23949				if (allBtnGroups.length > 0) {
23950					editorHeader = this.__buildButtons([allBtnGroups], editorHeader);
23951				}
23952
23953				if (options.fullscreen.enable) {
23954					editorHeader.append('<div class="md-controls"><a class="md-control md-control-fullscreen" href="#"><span class="' + this.__getIcon(options.fullscreen.icons.fullscreenOn) + '"></span></a></div>').on('click', '.md-control-fullscreen', function(e) {
23955						e.preventDefault();
23956						instance.setFullscreen(true);
23957					});
23958				}
23959
23960				editor.append(editorHeader);
23961
23962				// Wrap the textarea
23963				if (container.is('textarea')) {
23964					container.before(editor);
23965					textarea = container;
23966					textarea.addClass('md-input');
23967					editor.append(textarea);
23968				} else {
23969					var rawContent = (typeof toMarkdown == 'function') ? toMarkdown(container.html()) : container.html(),
23970						currentContent = $.trim(rawContent);
23971
23972					// This is some arbitrary content that could be edited
23973					textarea = $('<textarea/>', {
23974						'class': 'md-input',
23975						'val': currentContent
23976					});
23977
23978					editor.append(textarea);
23979
23980					// Save the editable
23981					editable.el = container;
23982					editable.type = container.prop('tagName').toLowerCase();
23983					editable.content = container.html();
23984
23985					$(container[0].attributes).each(function() {
23986						editable.attrKeys.push(this.nodeName);
23987						editable.attrValues.push(this.nodeValue);
23988					});
23989
23990					// Set editor to block the original container
23991					container.replaceWith(editor);
23992				}
23993
23994				var editorFooter = $('<div/>', {
23995						'class': 'md-footer'
23996					}),
23997					createFooter = false,
23998					footer = '';
23999				// Create the footer if savable
24000				if (options.savable) {
24001					createFooter = true;
24002					var saveHandler = 'cmdSave';
24003
24004					// Register handler and callback
24005					handler.push(saveHandler);
24006					callback.push(options.onSave);
24007
24008					editorFooter.append('<button class="btn btn-success" data-provider="' +
24009						ns +
24010						'" data-handler="' +
24011						saveHandler +
24012						'"><i class="icon icon-white icon-ok"></i> ' +
24013						this.__localize('Save') +
24014						'</button>');
24015
24016
24017				}
24018
24019				footer = typeof options.footer === 'function' ? options.footer(this) : options.footer;
24020
24021				if ($.trim(footer) !== '') {
24022					createFooter = true;
24023					editorFooter.append(footer);
24024				}
24025
24026				if (createFooter) editor.append(editorFooter);
24027
24028				// Set width
24029				if (options.width && options.width !== 'inherit') {
24030					if (jQuery.isNumeric(options.width)) {
24031						editor.css('display', 'table');
24032						textarea.css('width', options.width + 'px');
24033					} else {
24034						editor.addClass(options.width);
24035					}
24036				}
24037
24038				// Set height
24039				if (options.height && options.height !== 'inherit') {
24040					if (jQuery.isNumeric(options.height)) {
24041						var height = options.height;
24042						if (editorHeader) height = Math.max(0, height - editorHeader.outerHeight());
24043						if (editorFooter) height = Math.max(0, height - editorFooter.outerHeight());
24044						textarea.css('height', height + 'px');
24045					} else {
24046						editor.addClass(options.height);
24047					}
24048				}
24049
24050				// Reference
24051				this.$editor = editor;
24052				this.$textarea = textarea;
24053				this.$editable = editable;
24054				this.$oldContent = this.getContent();
24055
24056				this.__setListener();
24057				this.__setEventListeners();
24058
24059				// Set editor attributes, data short-hand API and listener
24060				this.$editor.attr('id', (new Date()).getTime());
24061				this.$editor.on('click', '[data-provider="bootstrap-markdown"]', $.proxy(this.__handle, this));
24062
24063				if (this.$element.is(':disabled') || this.$element.is('[readonly]')) {
24064					this.$editor.addClass('md-editor-disabled');
24065					this.disableButtons('all');
24066				}
24067
24068				if (this.eventSupported('keydown') && typeof jQuery.hotkeys === 'object') {
24069					editorHeader.find('[data-provider="bootstrap-markdown"]').each(function() {
24070						var $button = $(this),
24071							hotkey = $button.attr('data-hotkey');
24072						if (hotkey.toLowerCase() !== '') {
24073							textarea.bind('keydown', hotkey, function() {
24074								$button.trigger('click');
24075								return false;
24076							});
24077						}
24078					});
24079				}
24080
24081				if (options.initialstate === 'preview') {
24082					this.showPreview();
24083				} else if (options.initialstate === 'fullscreen' && options.fullscreen.enable) {
24084					this.setFullscreen(true);
24085				}
24086
24087			} else {
24088				this.$editor.show();
24089			}
24090
24091			if (options.autofocus) {
24092				this.$textarea.focus();
24093				this.$editor.addClass('active');
24094			}
24095
24096			if (options.fullscreen.enable && options.fullscreen !== false) {
24097				this.$editor.append('<div class="md-fullscreen-controls">' +
24098					'<a href="#" class="exit-fullscreen" title="Exit fullscreen"><span class="' + this.__getIcon(options.fullscreen.icons.fullscreenOff) + '">' +
24099					'</span></a>' +
24100					'</div>');
24101				this.$editor.on('click', '.exit-fullscreen', function(e) {
24102					e.preventDefault();
24103					instance.setFullscreen(false);
24104				});
24105			}
24106
24107			// hide hidden buttons from options
24108			this.hideButtons(options.hiddenButtons);
24109
24110			// disable disabled buttons from options
24111			this.disableButtons(options.disabledButtons);
24112
24113			// enable dropZone if available and configured
24114			if (options.dropZoneOptions) {
24115				if (this.$editor.dropzone) {
24116					if(!options.dropZoneOptions.init) {
24117						options.dropZoneOptions.init = function() {
24118							var caretPos = 0;
24119							this.on('drop', function(e) {
24120								caretPos = textarea.prop('selectionStart');
24121							});
24122							this.on('success', function(file, path) {
24123								var text = textarea.val();
24124								textarea.val(text.substring(0, caretPos) + '\n![description](' + path + ')\n' + text.substring(caretPos));
24125							});
24126							this.on('error', function(file, error, xhr) {
24127								console.log('Error:', error);
24128							});
24129						};
24130					}
24131					this.$editor.addClass('dropzone');
24132					this.$editor.dropzone(options.dropZoneOptions);
24133				} else {
24134					console.log('dropZoneOptions was configured, but DropZone was not detected.');
24135				}
24136			}
24137
24138			// enable data-uris via drag and drop
24139			if (options.enableDropDataUri === true) {
24140				this.$editor.on('drop', function(e) {
24141					var caretPos = textarea.prop('selectionStart');
24142					e.stopPropagation();
24143					e.preventDefault();
24144					$.each(e.originalEvent.dataTransfer.files, function(index, file){
24145						var fileReader = new FileReader();
24146						fileReader.onload = (function(file) {
24147							var type = file.type.split('/')[0];
24148							return function(e) {
24149								var text = textarea.val();
24150								if (type === 'image')
24151									textarea.val(text.substring(0, caretPos) + '\n<img src="'+ e.target.result  +'" />\n' + text.substring(caretPos) );
24152								else
24153									textarea.val(text.substring(0, caretPos) + '\n<a href="'+ e.target.result  +'">Download ' + file.name + '</a>\n' + text.substring(caretPos) );
24154							};
24155						})(file);
24156						fileReader.readAsDataURL(file);
24157					});
24158				});
24159			}
24160
24161			// Trigger the onShow hook
24162			options.onShow(this);
24163
24164			return this;
24165		},
24166		parseContent: function(val) {
24167			var content;
24168
24169			// parse with supported markdown parser
24170			val = val || this.$textarea.val();
24171
24172			if (this.$options.parser) {
24173				content = this.$options.parser(val);
24174			} else if (typeof markdown == 'object') {
24175				content = markdown.toHTML(val);
24176			} else if (typeof marked == 'function') {
24177				content = marked(val);
24178			} else {
24179				content = val;
24180			}
24181
24182			return content;
24183		},
24184		showPreview: function() {
24185			var options = this.$options,
24186				container = this.$textarea,
24187				afterContainer = container.next(),
24188				replacementContainer = $('<div/>', {
24189					'class': 'md-preview',
24190					'data-provider': 'markdown-preview'
24191				}),
24192				content,
24193				callbackContent;
24194
24195			if (this.$isPreview === true) {
24196				// Avoid sequenced element creation on misused scenario
24197				// @see https://github.com/toopay/bootstrap-markdown/issues/170
24198				return this;
24199			}
24200
24201			// Give flag that tells the editor to enter preview mode
24202			this.$isPreview = true;
24203			// Disable all buttons
24204			this.disableButtons('all').enableButtons('cmdPreview');
24205
24206			// Try to get the content from callback
24207			callbackContent = options.onPreview(this, replacementContainer);
24208			// Set the content based on the callback content if string, otherwise parse value from textarea
24209			content = typeof callbackContent == 'string' ? callbackContent : this.parseContent();
24210
24211			// Build preview element
24212			replacementContainer.html(content);
24213
24214			if (afterContainer && afterContainer.attr('class') == 'md-footer') {
24215				// If there is footer element, insert the preview container before it
24216				replacementContainer.insertBefore(afterContainer);
24217			} else {
24218				// Otherwise, just append it after textarea
24219				container.parent().append(replacementContainer);
24220			}
24221
24222			// Set the preview element dimensions
24223			replacementContainer.css({
24224				"width": container.outerWidth() + 'px',
24225				"min-height": container.outerHeight() + 'px',
24226				"height": "auto"
24227			});
24228
24229			if (this.$options.resize) {
24230				replacementContainer.css('resize', this.$options.resize);
24231			}
24232
24233			// Hide the last-active textarea
24234			container.hide();
24235
24236			// Attach the editor instances
24237			replacementContainer.data('markdown', this);
24238
24239			if (this.$element.is(':disabled') || this.$element.is('[readonly]')) {
24240				this.$editor.addClass('md-editor-disabled');
24241				this.disableButtons('all');
24242			}
24243
24244			return this;
24245		},
24246		hidePreview: function() {
24247			// Give flag that tells the editor to quit preview mode
24248			this.$isPreview = false;
24249
24250			// Obtain the preview container
24251			var container = this.$editor.find('div[data-provider="markdown-preview"]');
24252
24253			// Remove the preview container
24254			container.remove();
24255
24256			// Enable all buttons
24257			this.enableButtons('all');
24258			// Disable configured disabled buttons
24259			this.disableButtons(this.$options.disabledButtons);
24260
24261			// Perform any callbacks
24262			this.$options.onPreviewEnd(this);
24263
24264			// Back to the editor
24265			this.$textarea.show();
24266			this.__setListener();
24267
24268			return this;
24269		},
24270		isDirty: function() {
24271			return this.$oldContent != this.getContent();
24272		},
24273		getContent: function() {
24274			return this.$textarea.val();
24275		},
24276		setContent: function(content) {
24277			this.$textarea.val(content);
24278
24279			return this;
24280		},
24281		findSelection: function(chunk) {
24282			var content = this.getContent(),
24283				startChunkPosition;
24284
24285			if (startChunkPosition = content.indexOf(chunk), startChunkPosition >= 0 && chunk.length > 0) {
24286				var oldSelection = this.getSelection(),
24287					selection;
24288
24289				this.setSelection(startChunkPosition, startChunkPosition + chunk.length);
24290				selection = this.getSelection();
24291
24292				this.setSelection(oldSelection.start, oldSelection.end);
24293
24294				return selection;
24295			} else {
24296				return null;
24297			}
24298		},
24299		getSelection: function() {
24300
24301			var e = this.$textarea[0];
24302
24303			return (
24304
24305				('selectionStart' in e && function() {
24306					var l = e.selectionEnd - e.selectionStart;
24307					return {
24308						start: e.selectionStart,
24309						end: e.selectionEnd,
24310						length: l,
24311						text: e.value.substr(e.selectionStart, l)
24312					};
24313				}) ||
24314
24315				/* browser not supported */
24316				function() {
24317					return null;
24318				}
24319
24320			)();
24321
24322		},
24323		setSelection: function(start, end) {
24324
24325			var e = this.$textarea[0];
24326
24327			return (
24328
24329				('selectionStart' in e && function() {
24330					e.selectionStart = start;
24331					e.selectionEnd = end;
24332					return;
24333				}) ||
24334
24335				/* browser not supported */
24336				function() {
24337					return null;
24338				}
24339
24340			)();
24341
24342		},
24343		replaceSelection: function(text) {
24344
24345			var e = this.$textarea[0];
24346
24347			return (
24348
24349				('selectionStart' in e && function() {
24350					e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length);
24351					// Set cursor to the last replacement end
24352					e.selectionStart = e.value.length;
24353					return this;
24354				}) ||
24355
24356				/* browser not supported */
24357				function() {
24358					e.value += text;
24359					return jQuery(e);
24360				}
24361
24362			)();
24363		},
24364		getNextTab: function() {
24365			// Shift the nextTab
24366			if (this.$nextTab.length === 0) {
24367				return null;
24368			} else {
24369				var nextTab, tab = this.$nextTab.shift();
24370
24371				if (typeof tab == 'function') {
24372					nextTab = tab();
24373				} else if (typeof tab == 'object' && tab.length > 0) {
24374					nextTab = tab;
24375				}
24376
24377				return nextTab;
24378			}
24379		},
24380		setNextTab: function(start, end) {
24381			// Push new selection into nextTab collections
24382			if (typeof start == 'string') {
24383				var that = this;
24384				this.$nextTab.push(function() {
24385					return that.findSelection(start);
24386				});
24387			} else if (typeof start == 'number' && typeof end == 'number') {
24388				var oldSelection = this.getSelection();
24389
24390				this.setSelection(start, end);
24391				this.$nextTab.push(this.getSelection());
24392
24393				this.setSelection(oldSelection.start, oldSelection.end);
24394			}
24395
24396			return;
24397		},
24398		__parseButtonNameParam: function(names) {
24399			return typeof names == 'string' ?
24400				names.split(' ') :
24401				names;
24402
24403		},
24404		enableButtons: function(name) {
24405			var buttons = this.__parseButtonNameParam(name),
24406				that = this;
24407
24408			$.each(buttons, function(i, v) {
24409				that.__alterButtons(buttons[i], function(el) {
24410					el.removeAttr('disabled');
24411				});
24412			});
24413
24414			return this;
24415		},
24416		disableButtons: function(name) {
24417			var buttons = this.__parseButtonNameParam(name),
24418				that = this;
24419
24420			$.each(buttons, function(i, v) {
24421				that.__alterButtons(buttons[i], function(el) {
24422					el.attr('disabled', 'disabled');
24423				});
24424			});
24425
24426			return this;
24427		},
24428		hideButtons: function(name) {
24429			var buttons = this.__parseButtonNameParam(name),
24430				that = this;
24431
24432			$.each(buttons, function(i, v) {
24433				that.__alterButtons(buttons[i], function(el) {
24434					el.addClass('hidden');
24435				});
24436			});
24437
24438			return this;
24439		},
24440		showButtons: function(name) {
24441			var buttons = this.__parseButtonNameParam(name),
24442				that = this;
24443
24444			$.each(buttons, function(i, v) {
24445				that.__alterButtons(buttons[i], function(el) {
24446					el.removeClass('hidden');
24447				});
24448			});
24449
24450			return this;
24451		},
24452		eventSupported: function(eventName) {
24453			var isSupported = eventName in this.$element;
24454			if (!isSupported) {
24455				this.$element.setAttribute(eventName, 'return;');
24456				isSupported = typeof this.$element[eventName] === 'function';
24457			}
24458			return isSupported;
24459		},
24460		keyup: function(e) {
24461			var blocked = false;
24462			switch (e.keyCode) {
24463				case 40: // down arrow
24464				case 38: // up arrow
24465				case 16: // shift
24466				case 17: // ctrl
24467				case 18: // alt
24468					break;
24469
24470				case 9: // tab
24471					var nextTab;
24472					if (nextTab = this.getNextTab(), nextTab !== null) {
24473						// Get the nextTab if exists
24474						var that = this;
24475						setTimeout(function() {
24476							that.setSelection(nextTab.start, nextTab.end);
24477						}, 500);
24478
24479						blocked = true;
24480					} else {
24481						// The next tab's memory contains nothing...
24482						// check the cursor position to determine tab action
24483						var cursor = this.getSelection();
24484
24485						if (cursor.start == cursor.end && cursor.end == this.getContent().length) {
24486							// The cursor has reached the end of the content
24487							blocked = false;
24488						} else {
24489							// Put the cursor to the end
24490							this.setSelection(this.getContent().length, this.getContent().length);
24491
24492							blocked = true;
24493						}
24494					}
24495
24496					break;
24497
24498				case 13: // enter
24499					blocked = false;
24500					var chars = this.getContent().split('');
24501					var enterIndex = this.getSelection().start;
24502					var priorNewlineIndex = -1; // initial line break at before index 0
24503
24504					// traverse backwards through chars to check if last line break was num/bullet item
24505					for (var i = enterIndex - 2; i >= 0; i--) {
24506						if (chars[i] === '\n') {
24507							priorNewlineIndex = i;
24508							break;
24509						}
24510					}
24511
24512					if (chars.slice(priorNewlineIndex + 1, priorNewlineIndex + 4).join('') == '---') {
24513						break;
24514					}
24515
24516					var charFollowingLastLineBreak = chars[priorNewlineIndex + 1];
24517					if (charFollowingLastLineBreak === '-') {
24518						this.addBullet(enterIndex);
24519					} else if ($.isNumeric(charFollowingLastLineBreak)) {
24520						var numBullet = this.getBulletNumber(priorNewlineIndex + 1);
24521						if (numBullet) {
24522							this.addNumberedBullet(enterIndex, numBullet);
24523						}
24524					}
24525					break;
24526
24527				case 27: // escape
24528					if (this.$isFullscreen) this.setFullscreen(false);
24529					blocked = false;
24530					break;
24531
24532				default:
24533					blocked = false;
24534			}
24535
24536			if (blocked) {
24537				e.stopPropagation();
24538				e.preventDefault();
24539			}
24540
24541			this.$options.onChange(this);
24542		},
24543		insertContent: function(index, content) {
24544			var firstHalf = this.getContent().slice(0, index);
24545			var secondHalf = this.getContent().slice(index + 1);
24546			this.setContent(firstHalf.concat(content).concat(secondHalf));
24547		},
24548		addBullet: function(index) {
24549			this.insertContent(index, '- \n');
24550			this.setSelection(index + 2, index + 2); // Put the cursor after the bullet
24551		},
24552		addNumberedBullet: function(index, num) {
24553			var numBullet = (num + 1) + '. \n';
24554			this.insertContent(index, numBullet);
24555
24556			var prefixLength = num.toString().length + 2;
24557			this.setSelection(index + prefixLength, index + prefixLength); // Put the cursor after the number
24558		},
24559		getBulletNumber: function(startIndex) {
24560			var bulletNum = this.getContent().slice(startIndex).split('.')[0];
24561			return $.isNumeric(bulletNum) ? parseInt(bulletNum) : null;
24562		},
24563		change: function(e) {
24564			this.$options.onChange(this);
24565			return this;
24566		},
24567		select: function(e) {
24568			this.$options.onSelect(this);
24569			return this;
24570		},
24571		focus: function(e) {
24572			var options = this.$options,
24573				isHideable = options.hideable,
24574				editor = this.$editor;
24575
24576			editor.addClass('active');
24577
24578			// Blur other markdown(s)
24579			$(document).find('.md-editor').each(function() {
24580				if ($(this).attr('id') !== editor.attr('id')) {
24581					var attachedMarkdown;
24582
24583					if (attachedMarkdown = $(this).find('textarea').data('markdown'),
24584					attachedMarkdown === null) {
24585						attachedMarkdown = $(this).find('div[data-provider="markdown-preview"]').data('markdown');
24586					}
24587
24588					if (attachedMarkdown) {
24589						attachedMarkdown.blur();
24590					}
24591				}
24592			});
24593
24594			// Trigger the onFocus hook
24595			options.onFocus(this);
24596
24597			return this;
24598		},
24599		blur: function(e) {
24600			var options = this.$options,
24601				isHideable = options.hideable,
24602				editor = this.$editor,
24603				editable = this.$editable;
24604
24605			if (editor.hasClass('active') || this.$element.parent().length === 0) {
24606				editor.removeClass('active');
24607
24608				if (isHideable) {
24609					// Check for editable elements
24610					if (editable.el !== null) {
24611						// Build the original element
24612						var oldElement = $('<' + editable.type + '/>'),
24613							content = this.getContent(),
24614							currentContent = this.parseContent(content);
24615
24616						$(editable.attrKeys).each(function(k, v) {
24617							oldElement.attr(editable.attrKeys[k], editable.attrValues[k]);
24618						});
24619
24620						// Get the editor content
24621						oldElement.html(currentContent);
24622
24623						editor.replaceWith(oldElement);
24624					} else {
24625						editor.hide();
24626					}
24627				}
24628
24629				// Trigger the onBlur hook
24630				options.onBlur(this);
24631			}
24632
24633			return this;
24634		}
24635
24636	};
24637
24638	/* MARKDOWN PLUGIN DEFINITION
24639   * ========================== */
24640
24641	var old = $.fn.markdown;
24642
24643	$.fn.markdown = function(option) {
24644		return this.each(function() {
24645			var $this = $(this),
24646				data = $this.data('markdown'),
24647				options = typeof option == 'object' && option;
24648			if (!data)
24649				$this.data('markdown', (data = new Markdown(this, options)));
24650		});
24651	};
24652
24653	$.fn.markdown.messages = {};
24654
24655	$.fn.markdown.defaults = {
24656		/* Editor Properties */
24657		autofocus: false,
24658		hideable: false,
24659		savable: false,
24660		width: 'inherit',
24661		height: 'inherit',
24662		resize: 'none',
24663		iconlibrary: 'glyph',
24664		language: 'en',
24665		initialstate: 'editor',
24666		parser: null,
24667		dropZoneOptions: null,
24668		enableDropDataUri: false,
24669
24670		/* Buttons Properties */
24671		buttons: [
24672			[{
24673				name: 'groupFont',
24674				data: [{
24675					name: 'cmdBold',
24676					hotkey: 'Ctrl+B',
24677					title: 'Bold',
24678					icon: {
24679						glyph: 'glyphicon glyphicon-bold',
24680						fa: 'fa fa-bold',
24681						'fa-3': 'icon-bold',
24682						'fa-5': 'fas fa-bold',
24683						octicons: 'octicon octicon-bold'
24684					},
24685					callback: function(e) {
24686						// Give/remove ** surround the selection
24687						var chunk, cursor, selected = e.getSelection(),
24688							content = e.getContent();
24689
24690						if (selected.length === 0) {
24691							// Give extra word
24692							chunk = e.__localize('strong text');
24693						} else {
24694							chunk = selected.text;
24695						}
24696
24697						// transform selection and set the cursor into chunked text
24698						if (content.substr(selected.start - 2, 2) === '**' &&
24699							content.substr(selected.end, 2) === '**') {
24700							e.setSelection(selected.start - 2, selected.end + 2);
24701							e.replaceSelection(chunk);
24702							cursor = selected.start - 2;
24703						} else {
24704							e.replaceSelection('**' + chunk + '**');
24705							cursor = selected.start + 2;
24706						}
24707
24708						// Set the cursor
24709						e.setSelection(cursor, cursor + chunk.length);
24710					}
24711				}, {
24712					name: 'cmdItalic',
24713					title: 'Italic',
24714					hotkey: 'Ctrl+I',
24715					icon: {
24716						glyph: 'glyphicon glyphicon-italic',
24717						fa: 'fa fa-italic',
24718						'fa-3': 'icon-italic',
24719						'fa-5': 'fas fa-italic',
24720						octicons: 'octicon octicon-italic'
24721					},
24722					callback: function(e) {
24723						// Give/remove * surround the selection
24724						var chunk, cursor, selected = e.getSelection(),
24725							content = e.getContent();
24726
24727						if (selected.length === 0) {
24728							// Give extra word
24729							chunk = e.__localize('emphasized text');
24730						} else {
24731							chunk = selected.text;
24732						}
24733
24734						// transform selection and set the cursor into chunked text
24735						if (content.substr(selected.start - 1, 1) === '_' &&
24736							content.substr(selected.end, 1) === '_') {
24737							e.setSelection(selected.start - 1, selected.end + 1);
24738							e.replaceSelection(chunk);
24739							cursor = selected.start - 1;
24740						} else {
24741							e.replaceSelection('_' + chunk + '_');
24742							cursor = selected.start + 1;
24743						}
24744
24745						// Set the cursor
24746						e.setSelection(cursor, cursor + chunk.length);
24747					}
24748				}, {
24749					name: 'cmdHeading',
24750					title: 'Heading',
24751					hotkey: 'Ctrl+H',
24752					icon: {
24753						glyph: 'glyphicon glyphicon-header',
24754						fa: 'fa fa-header',
24755						'fa-3': 'icon-font',
24756						'fa-5': 'fas fa-heading',
24757						octicons: 'octicon octicon-text-size'
24758					},
24759					callback: function(e) {
24760						// Append/remove ### surround the selection
24761						var chunk, cursor, selected = e.getSelection(),
24762							content = e.getContent(),
24763							pointer, prevChar;
24764
24765						if (selected.length === 0) {
24766							// Give extra word
24767							chunk = e.__localize('heading text');
24768						} else {
24769							chunk = selected.text + '\n';
24770						}
24771
24772						// transform selection and set the cursor into chunked text
24773						if ((pointer = 4, content.substr(selected.start - pointer, pointer) === '### ') ||
24774							(pointer = 3, content.substr(selected.start - pointer, pointer) === '###')) {
24775							e.setSelection(selected.start - pointer, selected.end);
24776							e.replaceSelection(chunk);
24777							cursor = selected.start - pointer;
24778						} else if (selected.start > 0 && (prevChar = content.substr(selected.start - 1, 1), !!prevChar && prevChar != '\n')) {
24779							e.replaceSelection('\n\n### ' + chunk);
24780							cursor = selected.start + 6;
24781						} else {
24782							// Empty string before element
24783							e.replaceSelection('### ' + chunk);
24784							cursor = selected.start + 4;
24785						}
24786
24787						// Set the cursor
24788						e.setSelection(cursor, cursor + chunk.length);
24789					}
24790				}]
24791			}, {
24792				name: 'groupLink',
24793				data: [{
24794					name: 'cmdUrl',
24795					title: 'URL/Link',
24796					hotkey: 'Ctrl+L',
24797					icon: {
24798						glyph: 'glyphicon glyphicon-link',
24799						fa: 'fa fa-link',
24800						'fa-3': 'icon-link',
24801						'fa-5': 'fas fa-link',
24802						octicons: 'octicon octicon-link'
24803					},
24804					callback: function(e) {
24805						// Give [] surround the selection and prepend the link
24806						var chunk, cursor, selected = e.getSelection(),
24807							content = e.getContent(),
24808							link;
24809
24810						if (selected.length === 0) {
24811							// Give extra word
24812							chunk = e.__localize('enter link description here');
24813						} else {
24814							chunk = selected.text;
24815						}
24816
24817						link = prompt(e.__localize('Insert Hyperlink'), 'http://');
24818
24819						var urlRegex = new RegExp('^((http|https)://|(mailto:)|(//))[a-z0-9]', 'i');
24820						if (link !== null && link !== '' && link !== 'http://' && urlRegex.test(link)) {
24821							// transform selection and set the cursor into chunked text
24822							e.replaceSelection('[' + chunk + '](' + link + ')');
24823							cursor = selected.start + 1;
24824
24825							// Set the cursor
24826							e.setSelection(cursor, cursor + chunk.length);
24827						}
24828					}
24829				}, {
24830					name: 'cmdImage',
24831					title: 'Image',
24832					hotkey: 'Ctrl+G',
24833					icon: {
24834						glyph: 'glyphicon glyphicon-picture',
24835						fa: 'fa fa-picture-o',
24836						'fa-3': 'icon-picture',
24837						'fa-5': 'far fa-image',
24838						octicons: 'octicon octicon-file-media'
24839					},
24840					callback: function(e) {
24841						// Give ![] surround the selection and prepend the image link
24842						var chunk, cursor, selected = e.getSelection(),
24843							content = e.getContent(),
24844							link;
24845
24846						if (selected.length === 0) {
24847							// Give extra word
24848							chunk = e.__localize('enter image description here');
24849						} else {
24850							chunk = selected.text;
24851						}
24852
24853						link = prompt(e.__localize('Insert Image Hyperlink'), 'http://');
24854
24855						var urlRegex = new RegExp('^((http|https)://|(//))[a-z0-9]', 'i');
24856						if (link !== null && link !== '' && link !== 'http://' && urlRegex.test(link)) {
24857							var sanitizedLink = $('<div>' + link + '</div>').text();
24858
24859							// transform selection and set the cursor into chunked text
24860							e.replaceSelection('![' + chunk + '](' + sanitizedLink + ' "' + e.__localize('enter image title here') + '")');
24861							cursor = selected.start + 2;
24862
24863							// Set the next tab
24864							e.setNextTab(e.__localize('enter image title here'));
24865
24866							// Set the cursor
24867							e.setSelection(cursor, cursor + chunk.length);
24868						}
24869					}
24870				}]
24871			}, {
24872				name: 'groupMisc',
24873				data: [{
24874					name: 'cmdList',
24875					hotkey: 'Ctrl+U',
24876					title: 'Unordered List',
24877					icon: {
24878						glyph: 'glyphicon glyphicon-list',
24879						fa: 'fa fa-list',
24880						'fa-3': 'icon-list-ul',
24881						'fa-5': 'fas fa-list-ul',
24882						octicons: 'octicon octicon-list-unordered'
24883					},
24884					callback: function(e) {
24885						// Prepend/Give - surround the selection
24886						var chunk, cursor, selected = e.getSelection(),
24887							content = e.getContent();
24888
24889						// transform selection and set the cursor into chunked text
24890						if (selected.length === 0) {
24891							// Give extra word
24892							chunk = e.__localize('list text here');
24893
24894							e.replaceSelection('- ' + chunk);
24895							// Set the cursor
24896							cursor = selected.start + 2;
24897						} else {
24898							if (selected.text.indexOf('\n') < 0) {
24899								chunk = selected.text;
24900
24901								e.replaceSelection('- ' + chunk);
24902
24903								// Set the cursor
24904								cursor = selected.start + 2;
24905							} else {
24906								var list = [];
24907
24908								list = selected.text.split('\n');
24909								chunk = list[0];
24910
24911								$.each(list, function(k, v) {
24912									list[k] = '- ' + v;
24913								});
24914
24915								e.replaceSelection('\n\n' + list.join('\n'));
24916
24917								// Set the cursor
24918								cursor = selected.start + 4;
24919							}
24920						}
24921
24922						// Set the cursor
24923						e.setSelection(cursor, cursor + chunk.length);
24924					}
24925				}, {
24926					name: 'cmdListO',
24927					hotkey: 'Ctrl+O',
24928					title: 'Ordered List',
24929					icon: {
24930						glyph: 'glyphicon glyphicon-th-list',
24931						fa: 'fa fa-list-ol',
24932						'fa-3': 'icon-list-ol',
24933						'fa-5': 'fas fa-list-ol',
24934						octicons: 'octicon octicon-list-ordered'
24935					},
24936					callback: function(e) {
24937
24938						// Prepend/Give - surround the selection
24939						var chunk, cursor, selected = e.getSelection(),
24940							content = e.getContent();
24941
24942						// transform selection and set the cursor into chunked text
24943						if (selected.length === 0) {
24944							// Give extra word
24945							chunk = e.__localize('list text here');
24946							e.replaceSelection('1. ' + chunk);
24947							// Set the cursor
24948							cursor = selected.start + 3;
24949						} else {
24950							if (selected.text.indexOf('\n') < 0) {
24951								chunk = selected.text;
24952
24953								e.replaceSelection('1. ' + chunk);
24954
24955								// Set the cursor
24956								cursor = selected.start + 3;
24957							} else {
24958								var i = 1;
24959								var list = [];
24960
24961								list = selected.text.split('\n');
24962								chunk = list[0];
24963
24964								$.each(list, function(k, v) {
24965									list[k] = i + '. ' + v;
24966									i++;
24967								});
24968
24969								e.replaceSelection('\n\n' + list.join('\n'));
24970
24971								// Set the cursor
24972								cursor = selected.start + 5;
24973							}
24974						}
24975
24976						// Set the cursor
24977						e.setSelection(cursor, cursor + chunk.length);
24978					}
24979				}, {
24980					name: 'cmdCode',
24981					hotkey: 'Ctrl+K',
24982					title: 'Code',
24983					icon: {
24984						glyph: 'glyphicon glyphicon-console',
24985						fa: 'fa fa-code',
24986						'fa-3': 'icon-code',
24987						'fa-5': 'fas fa-code',
24988						octicons: 'octicon octicon-code'
24989					},
24990					callback: function(e) {
24991						// Give/remove ** surround the selection
24992						var ch
24992unk, cursor, selected = e.getSelection(),
24993							content = e.getContent();
24994
24995						if (selected.length === 0) {
24996							// Give extra word
24997							chunk = e.__localize('code text here');
24998						} else {
24999							chunk = selected.text;
25000						}
25001
25002						// transform selection and set the cursor into chunked text
25003						if (content.substr(selected.start - 4, 4) === '```\n' &&
25004							content.substr(selected.end, 4) === '\n```') {
25005							e.setSelection(selected.start - 4, selected.end + 4);
25006							e.replaceSelection(chunk);
25007							cursor = selected.start - 4;
25008						} else if (content.substr(selected.start - 1, 1) === '`' &&
25009							content.substr(selected.end, 1) === '`') {
25010							e.setSelection(selected.start - 1, selected.end + 1);
25011							e.replaceSelection(chunk);
25012							cursor = selected.start - 1;
25013						} else if (content.indexOf('\n') > -1) {
25014							e.replaceSelection('```\n' + chunk + '\n```');
25015							cursor = selected.start + 4;
25016						} else {
25017							e.replaceSelection('`' + chunk + '`');
25018							cursor = selected.start + 1;
25019						}
25020
25021						// Set the cursor
25022						e.setSelection(cursor, cursor + chunk.length);
25023					}
25024				}, {
25025					name: 'cmdQuote',
25026					hotkey: 'Ctrl+Q',
25027					title: 'Quote',
25028					icon: {
25029						glyph: 'glyphicon glyphicon-comment',
25030						fa: 'fa fa-quote-left',
25031						'fa-3': 'icon-quote-left',
25032						'fa-5': 'fas fa-quote-left',
25033						octicons: 'octicon octicon-quote'
25034					},
25035					callback: function(e) {
25036						// Prepend/Give - surround the selection
25037						var chunk, cursor, selected = e.getSelection(),
25038							content = e.getContent();
25039
25040						// transform selection and set the cursor into chunked text
25041						if (selected.length === 0) {
25042							// Give extra word
25043							chunk = e.__localize('quote here');
25044
25045							e.replaceSelection('> ' + chunk);
25046
25047							// Set the cursor
25048							cursor = selected.start + 2;
25049						} else {
25050							if (selected.text.indexOf('\n') < 0) {
25051								chunk = selected.text;
25052
25053								e.replaceSelection('> ' + chunk);
25054
25055								// Set the cursor
25056								cursor = selected.start + 2;
25057							} else {
25058								var list = [];
25059
25060								list = selected.text.split('\n');
25061								chunk = list[0];
25062
25063								$.each(list, function(k, v) {
25064									list[k] = '> ' + v;
25065								});
25066
25067								e.replaceSelection('\n\n' + list.join('\n'));
25068
25069								// Set the cursor
25070								cursor = selected.start + 4;
25071							}
25072						}
25073
25074						// Set the cursor
25075						e.setSelection(cursor, cursor + chunk.length);
25076					}
25077				}]
25078			}, {
25079				name: 'groupUtil',
25080				data: [{
25081					name: 'cmdPreview',
25082					toggle: true,
25083					hotkey: 'Ctrl+P',
25084					title: 'Preview',
25085					btnText: 'Preview',
25086					btnClass: 'btn btn-primary btn-sm',
25087					icon: {
25088						glyph: 'glyphicon glyphicon-search',
25089						fa: 'fa fa-search',
25090						'fa-3': 'icon-search',
25091						'fa-5': 'fas fa-search',
25092						octicons: 'octicon octicon-search'
25093					},
25094					callback: function(e) {
25095						// Check the preview mode and toggle based on this flag
25096						var isPreview = e.$isPreview,
25097							content;
25098
25099						if (isPreview === false) {
25100							// Give flag that tells the editor to enter preview mode
25101							e.showPreview();
25102						} else {
25103							e.hidePreview();
25104						}
25105					}
25106				}]
25107			}]
25108		],
25109		customIcons: {},
25110		additionalButtons: [], // Place to hook more buttons by code
25111		reorderButtonGroups: [],
25112		hiddenButtons: [], // Default hidden buttons
25113		disabledButtons: [], // Default disabled buttons
25114		footer: '',
25115		fullscreen: {
25116			enable: true,
25117			icons: {
25118				fullscreenOn: {
25119					name: "fullscreenOn",
25120					icon: {
25121						fa: 'fa fa-expand',
25122						glyph: 'glyphicon glyphicon-fullscreen',
25123						'fa-3': 'icon-resize-full',
25124						'fa-5': 'fas fa-expand-arrows-alt',
25125						octicons: 'octicon octicon-link-external'
25126					}
25127				},
25128				fullscreenOff: {
25129					name: "fullscreenOff",
25130					icon: {
25131						fa: 'fa fa-compress',
25132						glyph: 'glyphicon glyphicon-fullscreen',
25133						'fa-3': 'icon-resize-small',
25134						'fa-5': 'fas fa-compress',
25135						octicons: 'octicon octicon-browser'
25136					}
25137				}
25138			}
25139		},
25140
25141		/* Events hook */
25142		onShow: function(e) {},
25143		onPreview: function(e) {},
25144		onPreviewEnd: function(e) {},
25145		onSave: function(e) {},
25146		onBlur: function(e) {},
25147		onFocus: function(e) {},
25148		onChange: function(e) {},
25149		onFullscreen: function(e) {},
25150		onFullscreenExit: function(e) {},
25151		onSelect: function(e) {}
25152	};
25153
25154	$.fn.markdown.Constructor = Markdown;
25155
25156
25157	/* MARKDOWN NO CONFLICT
25158   * ==================== */
25159
25160	$.fn.markdown.noConflict = function() {
25161		$.fn.markdown = old;
25162		return this;
25163	};
25164
25165	/* MARKDOWN GLOBAL FUNCTION & DATA-API
25166   * ==================================== */
25167	var initMarkdown = function(el) {
25168		var $this = el;
25169
25170		if ($this.data('markdown')) {
25171			$this.data('markdown').showEditor();
25172			return;
25173		}
25174
25175		$this.markdown();
25176	};
25177
25178	var blurNonFocused = function(e) {
25179		var $activeElement = $(document.activeElement);
25180
25181		// Blur event
25182		$(document).find('.md-editor').each(function() {
25183			var $this = $(this),
25184				focused = $activeElement.closest('.md-editor')[0] === this,
25185				attachedMarkdown = $this.find('textarea').data('markdown') ||
25186					$this.find('div[data-provider="markdown-preview"]').data('markdown');
25187
25188			if (attachedMarkdown && !focused) {
25189				attachedMarkdown.blur();
25190			}
25191		});
25192	};
25193
25194	$(document)
25195		.on('click.markdown.data-api', '[data-provide="markdown-editable"]', function(e) {
25196			initMarkdown($(this));
25197			e.preventDefault();
25198		})
25199		.on('click focusin', function(e) {
25200			blurNonFocused(e);
25201		})
25202		.ready(function() {
25203			$('textarea[data-provide="markdown"]').each(function() {
25204				initMarkdown($(this));
25205			});
25206		});
25207
25208}));
25209
25210/*
25211 * Arabic translation for bootstrap-markdown
25212 * George Ajam <[email protected]>
25213 */
25214(function ($) {
25215	$.fn.markdown.messages.nl = {
25216		'Bold': "غامق",
25217		'Italic': "مائل",
25218		'Heading': "عنوان",
25219		'URL/Link': "URL/رابط",
25220		'Image': "صورة",
25221		'List': "قائمة",
25222		'Preview': "استعراض",
25223		'strong text': "نص غامق",
25224		'emphasized text': "نص هام",
25225		'heading text': "العنوان",
25226		'enter link description here': "ادخل وصف الرابط هنا",
25227		'Insert Hyperlink': "ادخل الرابط هنا",
25228		'enter image description here': "ادخل وصف الصورة هنا",
25229		'Insert Image Hyperlink': "ادخل رابط الصورة هنا",
25230		'enter image title here': "ادخل عنوان الصورة هنا",
25231		'list text here': "اكتب النص هنا"
25232	};
25233}(jQuery));
25234
25235/**
25236 * Czech translation for bootstrap-markdown
25237 * Vít Kabele <[email protected]>
25238 */
25239(function ($) {
25240	$.fn.markdown.messages.cs = {
25241		'Bold': "Tučně",
25242		'Italic': "Kurzíva",
25243		'Heading': "Nadpis",
25244		'URL/Link': "URL/Odkaz",
25245		'Image': "Obrázek",
25246		'Unordered List': "Seznam",
25247		'Ordered List': "Seřazený seznam",
25248		'Code': "Úsek kódu",
25249		'Quote': "Citace",
25250		'Preview': "Náhled",
25251		'strong text': "tučný text",
25252		'emphasized text': "zdůrazněný text",
25253		'heading text': "text nadpisu",
25254		'enter link description here': "sem vlož popis odkazu",
25255		'Insert Hyperlink': "Vložit Hyperlink",
25256		'enter image description here': "sem vlož popis obrázku",
25257		'Insert Image Hyperlink': "Vlož adresu obrázku",
25258		'enter image title here': "sem vlož popis obrázku",
25259		'list text here': "položka seznamu"
25260	};
25261}(jQuery));
25262
25263/**
25264 * Danish translation for bootstrap-markdown
25265 * Dan Storm <[email protected]>
25266 */
25267(function ($) {
25268	$.fn.markdown.messages.da = {
25269		'Bold': 'Fed',
25270		'Italic': 'Kursiv',
25271		'Heading': 'Overskrift',
25272		'URL/Link': 'URL/Link',
25273		'Image': 'Billede',
25274		'List': 'Liste',
25275		'Preview': 'Forhåndsvisning',
25276		'strong text': 'stærk tekst',
25277		'emphasized text': 'fremhævet tekst',
25278		'heading text': 'overskrift tekst',
25279		'enter link description here': 'Skriv link beskrivelse her',
25280		'Insert Hyperlink': 'Indsæt link',
25281		'enter image description here': 'Indsæt billede beskrivelse her',
25282		'Insert Image Hyperlink': 'Indsæt billede link',
25283		'enter image title here': 'Indsæt billede titel',
25284		'list text here': 'Indsæt liste tekst her',
25285		'quote here': 'Indsæt citat her',
25286		'code text here': 'Indsæt kode her'
25287	};
25288}(jQuery));
25289
25290/**
25291 * German translation for bootstrap-markdown
25292 * Tobias Nitsche <[email protected]>
25293 */
25294(function ($) {
25295	$.fn.markdown.messages.de = {
25296		'Bold': "Fett",
25297		'Italic': "Kursiv",
25298		'Heading': "Überschrift",
25299		'URL/Link': "Link hinzufügen",
25300		'Image': "Bild hinzufügen",
25301		'Unordered List': "Unnummerierte Liste",
25302		'Ordered List': "Nummerierte Liste",
25303		'Code': "Quelltext",
25304		'code text here': "Quelltext hier einfügen",
25305		'Quote': "Zitat",
25306		'quote here': "Zitat hier einfügen",
25307		'Preview': "Vorschau",
25308		'Save': "Speichern",
25309		'strong text': "Sehr betonter Text",
25310		'emphasized text': "Betonter Text",
25311		'heading text': "Überschrift Text",
25312		'enter link description here': "Linkbeschreibung",
25313		'Insert Hyperlink': "URL",
25314		'enter image description here': "Bildbeschreibung",
25315		'Insert Image Hyperlink': "Bild-URL",
25316		'enter image title here': "Titel des Bildes",
25317		'list text here': "Aufzählungs-Text"
25318	};
25319}(jQuery));
25320
25321/**
25322 * Spanish translation for bootstrap-markdown
25323 * by Leandro Poblet <[email protected]>
25324 */
25325(function ($) {
25326	$.fn.markdown.messages.es = {
25327		'Bold': "Negrita",
25328		'Italic': "Itálica",
25329		'Heading': "Título",
25330		'URL/Link': "Inserte un link",
25331		'Image': "Inserte una imagen",
25332		'List': "Lista de items",
25333		'Unordered List': "Lista desordenada",
25334		'Ordered List': "Lista ordenada",
25335		'Code': "Código",
25336		'Quote': "Cita",
25337		'Preview': "Previsualizar",
25338		'strong text': "Texto importante",
25339		'emphasized text': "Texto con énfasis",
25340		'heading text': "Texto de título",
25341		'enter link description here': "Descripción del link",
25342		'Insert Hyperlink': "Inserte un hipervínculo",
25343		'enter image description here': "Descripción de la imagen",
25344		'Insert Image Hyperlink': "Inserte una imagen con un hipervínculo",
25345		'enter image title here': "Inserte una imagen con título",
25346		'list text here': "Texto de lista aquí",
25347		'code text here': "Código aquí",
25348		'quote here': "Cita aquí",
25349		'Save': "Guardar"
25350	};
25351}(jQuery));
25352
25353/**
25354 * Persian(Farsi) translation for bootstrap-markdown
25355 * Sajad Dehshiri <Pelakweb.ir>
25356 */
25357(function ($) {
25358	$.fn.markdown.messages.fa = {
25359		'Bold': "توپر",
25360		'Italic': "مورب",
25361		'Heading': "عنوان",
25362		'URL/Link': "پیوند",
25363		'Image': "تصویر",
25364		'List': "فهرست",
25365		'Preview': "پیش نمایش",
25366		'strong text': "متن ضخیم",
25367		'emphasized text': "نوشته تاکیدی",
25368		'heading text': "عنوان",
25369		'enter link description here': "توضیحات پیوند را بنویسید.",
25370		'Insert Hyperlink': "پیوند را درج نمایید:",
25371		'enter image description here': "توضیحی برای تصوی بنویسید.",
25372		'Insert Image Hyperlink': "آدرس تصویر را بنویسید.",
25373		'enter image title here': "عنوان تصویر را اینجا بنویسید",
25374		'list text here': "محل متن فهرست"
25375	};
25376}(jQuery));
25377
25378/**
25379 * French translation for bootstrap-markdown
25380 * Benoît Bourgeois <[email protected]>
25381 */
25382(function ($) {
25383	$.fn.markdown.messages.fr = {
25384		'Bold': "Gras",
25385		'Italic': "Italique",
25386		'Heading': "Titre",
25387		'URL/Link': "Insérer un lien HTTP",
25388		'Image': "Insérer une image",
25389		'List': "Liste à puces",
25390		'Preview': "Prévisualiser",
25391		'strong text': "texte important",
25392		'emphasized text': "texte en italique",
25393		'heading text': "texte d'entête",
25394		'enter link description here': "entrez la description du lien ici",
25395		'Insert Hyperlink': "Insérez le lien hypertexte",
25396		'enter image description here': "entrez la description de l'image ici",
25397		'Insert Image Hyperlink': "Insérez le lien hypertexte de l'image",
25398		'enter image title here': "entrez le titre de l'image ici",
25399		'list text here': "texte à puce ici",
25400		'Save': "Sauvegarder",
25401		'Ordered List': "Liste ordonnée",
25402		'Unordered List': "Liste désordonnée",
25403		'Quote': "Citation",
25404		'quote here': "Votre citation",
25405		'Code': "Code",
25406		'code text here': "écrire du code ici"
25407	};
25408}(jQuery));
25409
25410/**
25411 * Japanese translation for bootstrap-markdown
25412 * Kenta Murakami <[email protected]>
25413 */
25414(function ($) {
25415	$.fn.markdown.messages.ja = {
25416		'Bold': "太字",
25417		'Italic': "斜体",
25418		'Heading': "見出し",
25419		'URL/Link': "リンク",
25420		'Image': "画像",
25421		'Unordered List': "リスト",
25422		'Ordered List': "数字リスト",
25423		'Code': "コード",
25424		'Quote': "引用",
25425		'Preview': "プレビュー",
25426		'strong text': "太字",
25427		'emphasized text': "強調",
25428		'heading text': "見出し",
25429		'enter link description here': "リンク説明",
25430		'Insert Hyperlink': "リンク挿入",
25431		'enter image description here': "画像説明",
25432		'Insert Image Hyperlink': "画像挿入",
25433		'enter image title here': "画像タイトル",
25434		'list text here': "リスト挿入",
25435		'code text here': "コード",
25436		'quote here': "引用挿入"
25437	};
25438}(jQuery));
25439
25440/**
25441 + * Korean translation for bootstrap-markdown
25442 + * WoongBi Kim <[email protected]>
25443 + */
25444(function ($) {
25445	$.fn.markdown.messages.kr = {
25446		'Bold': "진하게",
25447		'Italic': "이탤릭체",
25448		'Heading': "머리글",
25449		'URL/Link': "링크주소",
25450		'Image': "이미지",
25451		'List': "리스트",
25452		'Preview': "미리보기",
25453		'strong text': "강한 강조 텍스트",
25454		'emphasized text': "강조 텍스트",
25455		'heading text': "머리글 텍스트",
25456		'enter link description here': "여기에 링크의 설명을 적으세요",
25457		'Insert Hyperlink': "하이퍼링크 삽입",
25458		'enter image description here': "여기세 이미지 설명을 적으세요",
25459		'Insert Image Hyperlink': "이미지 링크 삽입",
25460		'enter image title here': "여기에 이미지 제목을 적으세요",
25461		'list text here': "리스트 텍스트"
25462	};
25463}(jQuery));
25464
25465/**
25466 * Norwegian bokmål translation for bootstrap-markdown
25467 * Tobias Bohwalli <[email protected]>
25468 */
25469(function ($) {
25470	$.fn.markdown.messages.nb = {
25471		'Bold': 'Fet',
25472		'Italic': 'Kursiv',
25473		'Heading': 'Overskrift',
25474		'URL/Link': 'URL/Lenke',
25475		'Image': 'Bilde',
25476		'List': 'Liste',
25477		'Preview': 'Forhåndsvisning',
25478		'strong text': 'sterk tekst',
25479		'emphasized text': 'streket tekst',
25480		'heading text': 'overskriften tekst',
25481		'enter link description here': 'Skriv linken beskrivelse her',
25482		'Insert Hyperlink': 'Sett inn lenke',
25483		'enter image description here': 'Angi bildebeskrivelse her',
25484		'Insert Image Hyperlink': 'Sett inn lenke for bilde',
25485		'enter image title here': 'Angi bildetittel her',
25486		'list text here': 'liste tekst her'
25487	};
25488}(jQuery));
25489
25490/**
25491 * Dutch translation for bootstrap-markdown
25492 * Jeroen Thora <[email protected]>
25493 */
25494(function ($) {
25495	$.fn.markdown.messages.nl = {
25496		'Bold': "Vet",
25497		'Italic': "Cursief",
25498		'Heading': "Titel",
25499		'URL/Link': "URL/Link",
25500		'Image': "Afbeelding",
25501		'List': "Lijst",
25502		'Preview': "Voorbeeld",
25503		'strong text': "vet gedrukte tekst",
25504		'emphasized text': "schuin gedrukte tekst",
25505		'heading text': "Titel",
25506		'enter link description here': "Voer een link beschrijving in",
25507		'Insert Hyperlink': "Voer een http link in",
25508		'enter image description here': "Voer een afbeelding beschrijving in",
25509		'Insert Image Hyperlink': "Voer een afbeelding link in",
25510		'enter image title here': "Voer de afbeelding titel in",
25511		'list text here': "lijst item"
25512	};
25513}(jQuery));
25514
25515/**
25516 * Polish translation for bootstrap-markdown
25517 * Marek Kaput
25518 */
25519(function ($) {
25520	$.fn.markdown.messages.pl = {
25521		'Bold': "Pogrubienie",
25522		'Italic': "Kursywa",
25523		'Heading': "Nagłówek",
25524		'URL/Link': "Wstaw link",
25525		'Image': "Wstaw obrazek",
25526		'Unordered List': "Lista punktowana",
25527		'Ordered List': "Lista numerowana",
25528		'Code': "Kod źródłowy",
25529		'Quote': "Cytat",
25530		'Preview': "Podgląd",
25531		'strong text': "pogrubiony tekst",
25532		'emphasized text': "pochylony tekst",
25533		'heading text': "nagłówek",
25534		'enter link description here': "opis linka",
25535		'Insert Hyperlink': "Wstaw link",
25536		'enter image description here': "opis obrazka",
25537		'Insert Image Hyperlink': "Wstaw obrazek",
25538		'enter image title here': "tytuł obrazka",
25539		'list text here': "lista"
25540	};
25541}(jQuery));
25542
25543/**
25544 * Slovenian translation for bootstrap-markdown
25545 * Davor Padovan <[email protected]>
25546 */
25547(function ($) {
25548	$.fn.markdown.messages.sl = {
25549		'Bold': "Odebeljeno",
25550		'Italic': "Poševno",
25551		'Heading': "Naslov",
25552		'URL/Link': "Povezava",
25553		'Image': "Slika",
25554		'Unordered List': "Neurejen seznam",
25555		'Ordered List': "Urejen seznam",
25556		'Code': "Koda",
25557		'Quote': "Citat",
25558		'Preview': "Predogled",
25559		'strong text': "odebeljeno besedilo",
25560		'emphasized text': "poševno besedilo",
25561		'heading text': "naslov",
25562		'enter link description here': "opis povezave",
25563		'Insert Hyperlink': "Vstavi povezavo",
25564		'enter image description here': "opis slike",
25565		'Insert Image Hyperlink': "Vstavi povezavo do slike",
25566		'enter image title here': "naslov slike",
25567		'list text here': "seznam"
25568	};
25569}(jQuery));
25570
25571/**
25572 * Swedish translation for bootstrap-markdown
25573 * Tobias Bohwalli <[email protected]>
25574 */
25575(function ($) {
25576	$.fn.markdown.messages.sv = {
25577		'Bold': 'Fet',
25578		'Italic': 'Kursiv',
25579		'Heading': 'Rubrik',
25580		'URL/Link': 'URL/Länk',
25581		'Image': 'Bild',
25582		'List': 'Lista',
25583		'Preview': 'Förhandsgranska',
25584		'strong text': 'fet text',
25585		'emphasized text': 'överstruken text',
25586		'heading text': 'Rubrik',
25587		'enter link description here': 'Ange länk beskrivning här',
25588		'Insert Hyperlink': 'Sätt in länk',
25589		'enter image description here': 'Ange bild beskrivning här',
25590		'Insert Image Hyperlink': 'Sätt in länk för bild',
25591		'enter image title here': 'Ange bild rubrik här',
25592		'list text here': 'list text'
25593	};
25594}(jQuery));
25595
25596/**
25597 * Turkish translation for bootstrap-markdown
25598 * Serkan Algur <[email protected]>
25599 */
25600(function ($) {
25601	$.fn.markdown.messages.tr = {
25602		'Bold': "Kalın",
25603		'Italic': "İtalik",
25604		'Heading': "Başlık",
25605		'URL/Link': "Link ekle",
25606		'Image': "Resim ekle",
25607		'List': "Liste Oluşturun",
25608		'Preview': "Önizleme",
25609		'strong text': "kalın yazı",
25610		'emphasized text': "italik yazı",
25611		'heading text': "Başlık Yazısı",
25612		'enter link description here': "Link açıklamasını buraya girin",
25613		'Insert Hyperlink': "İnternet adresi girin",
25614		'enter image description here': "resim açıklamasını buraya ekleyin",
25615		'Insert Image Hyperlink': "Resim linkini ekleyin",
25616		'enter image title here': "resim başlığını buraya ekleyin",
25617		'list text here': "liste yazısı",
25618		'Save' : "Kaydet",
25619		'Ordered List' : "Numaralı Liste",
25620		'Unordered List' : "Madde imli liste",
25621		'Quote' : "Alıntı",
25622		'quote here' : "alıntıyı buraya ekleyin",
25623		'Code' : "Kod",
25624		'code text here' : "kodu buraya ekleyin"
25625	};
25626}(jQuery));
25627
25628/**
25629 * Chinese translation for bootstrap-markdown
25630 * benhaile <[email protected]>
25631 */
25632(function ($) {
25633	$.fn.markdown.messages.zh = {
25634		'Bold': "粗体",
25635		'Italic': "斜体",
25636		'Heading': "标题",
25637		'URL/Link': "链接",
25638		'Image': "图片",
25639		'List': "列表",
25640		'Unordered List': "无序列表",
25641		'Ordered List': "有序列表",
25642		'Code': "代码",
25643		'Quote': "引用",
25644		'Preview': "预览",
25645		'strong text': "粗体",
25646		'emphasized text': "强调",
25647		'heading text': "标题",
25648		'enter link description here': "输入链接说明",
25649		'Insert Hyperlink': "URL地址",
25650		'enter image description here': "输入图片说明",
25651		'Insert Image Hyperlink': "图片URL地址",
25652		'enter image title here': "在这里输入图片标题",
25653		'list text here': "这里是列表文本",
25654		'code text here': "这里输入代码",
25655		'quote here': "这里输入引用文本"
25656	};
25657}(jQuery));
25658
25659/*! DataTables 1.10.12
25660 * ©2008-2015 SpryMedia Ltd - datatables.net/license
25661 */
25662
25663/**
25664 * @summary     DataTables
25665 * @description Paginate, search and order HTML tables
25666 * @version     1.10.12
25667 * @file        jquery.dataTables.js
25668 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
25669 * @contact     www.sprymedia.co.uk/contact
25670 * @copyright   Copyright 2008-2015 SpryMedia Ltd.
25671 *
25672 * This source file is free software, available under the following license:
25673 *   MIT license - http://datatables.net/license
25674 *
25675 * This source file is distributed in the hope that it will be useful, but
25676 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25677 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
25678 *
25679 * For details please refer to: http://www.datatables.net
25680 */
25681
25682/*jslint evil: true, undef: true, browser: true */
25683/*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*/
25684
25685(function( factory ) {
25686	"use strict";
25687
25688	if ( typeof define === 'function' && define.amd ) {
25689		// AMD
25690		define( ['jquery'], function ( $ ) {
25691			return factory( $, window, document );
25692		} );
25693	}
25694	else if ( typeof exports === 'object' ) {
25695		// CommonJS
25696		module.exports = function (root, $) {
25697			if ( ! root ) {
25698				// CommonJS environments without a window global must pass a
25699				// root. This will give an error otherwise
25700				root = window;
25701			}
25702
25703			if ( ! $ ) {
25704				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
25705					require('jquery') :
25706					require('jquery')( root );
25707			}
25708
25709			return factory( $, root, root.document );
25710		};
25711	}
25712	else {
25713		// Browser
25714		factory( jQuery, window, document );
25715	}
25716}
25717(function( $, window, document, undefined ) {
25718	"use strict";
25719
25720	/**
25721	 * DataTables is a plug-in for the jQuery Javascript library. It is a highly
25722	 * flexible tool, based upon the foundations of progressive enhancement,
25723	 * which will add advanced interaction controls to any HTML table. For a
25724	 * full list of features please refer to
25725	 * [DataTables.net](href="http://datatables.net).
25726	 *
25727	 * Note that the `DataTable` object is not a global variable but is aliased
25728	 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
25729	 * be  accessed.
25730	 *
25731	 *  @class
25732	 *  @param {object} [init={}] Configuration object for DataTables. Options
25733	 *    are defined by {@link DataTable.defaults}
25734	 *  @requires jQuery 1.7+
25735	 *
25736	 *  @example
25737	 *    // Basic initialisation
25738	 *    $(document).ready( function {
25739	 *      $('#example').dataTable();
25740	 *    } );
25741	 *
25742	 *  @example
25743	 *    // Initialisation with configuration options - in this case, disable
25744	 *    // pagination and sorting.
25745	 *    $(document).ready( function {
25746	 *      $('#example').dataTable( {
25747	 *        "paginate": false,
25748	 *        "sort": false
25749	 *      } );
25750	 *    } );
25751	 */
25752	var DataTable = function ( options )
25753	{
25754		/**
25755		 * Perform a jQuery selector action on the table's TR elements (from the tbody) and
25756		 * return the resulting jQuery object.
25757		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
25758		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
25759		 *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
25760		 *    criterion ("applied") or all TR elements (i.e. no filter).
25761		 *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
25762		 *    Can be either 'current', whereby the current sorting of the table is used, or
25763		 *    'original' whereby the original order the data was read into the table is used.
25764		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
25765		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
25766		 *    'current' and filter is 'applied', regardless of what they might be given as.
25767		 *  @returns {object} jQuery object, filtered by the given selector.
25768		 *  @dtopt API
25769		 *  @deprecated Since v1.10
25770		 *
25771		 *  @example
25772		 *    $(document).ready(function() {
25773		 *      var oTable = $('#example').dataTable();
25774		 *
25775		 *      // Highlight every second row
25776		 *      oTable.$('tr:odd').css('backgroundColor', 'blue');
25777		 *    } );
25778		 *
25779		 *  @example
25780		 *    $(document).ready(function() {
25781		 *      var oTable = $('#example').dataTable();
25782		 *
25783		 *      // Filter to rows with 'Webkit' in them, add a background colour and then
25784		 *      // remove the filter, thus highlighting the 'Webkit' rows only.
25785		 *      oTable.fnFilter('Webkit');
25786		 *      oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
25787		 *      oTable.fnFilter('');
25788		 *    } );
25789		 */
25790		this.$ = function ( sSelector, oOpts )
25791		{
25792			return this.api(true).$( sSelector, oOpts );
25793		};
25794
25795
25796		/**
25797		 * Almost identical to $ in operation, but in this case returns the data for the matched
25798		 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
25799		 * rather than any descendants, so the data can be obtained for the row/cell. If matching
25800		 * rows are found, the data returned is the original data array/object that was used to
25801		 * create the row (or a generated array if from a DOM source).
25802		 *
25803		 * This method is often useful in-combination with $ where both functions are given the
25804		 * same parameters and the array indexes will match identically.
25805		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
25806		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
25807		 *  @param {string} [oOpts.filter=none] Select elements that meet the current filter
25808		 *    criterion ("applied") or all elements (i.e. no filter).
25809		 *  @param {string} [oOpts.order=current] Order of the data in the processed array.
25810		 *    Can be either 'current', whereby the current sorting of the table is used, or
25811		 *    'original' whereby the original order the data was read into the table is used.
25812		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
25813		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
25814		 *    'current' and filter is 'applied', regardless of what they might be given as.
25815		 *  @returns {array} Data for the matched elements. If any elements, as a result of the
25816		 *    selector, were not TR, TD or TH elements in the DataTable, they will have a null
25817		 *    entry in the array.
25818		 *  @dtopt API
25819		 *  @deprecated Since v1.10
25820		 *
25821		 *  @example
25822		 *    $(document).ready(function() {
25823		 *      var oTable = $('#example').dataTable();
25824		 *
25825		 *      // Get the data from the first row in the table
25826		 *      var data = oTable._('tr:first');
25827		 *
25828		 *      // Do something useful with the data
25829		 *      alert( "First cell is: "+data[0] );
25830		 *    } );
25831		 *
25832		 *  @example
25833		 *    $(document).ready(function() {
25834		 *      var oTable = $('#example').dataTable();
25835		 *
25836		 *      // Filter to 'Webkit' and get all data for
25837		 *      oTable.fnFilter('Webkit');
25838		 *      var data = oTable._('tr', {"search": "applied"});
25839		 *
25840		 *      // Do something with the data
25841		 *      alert( data.length+" rows matched the search" );
25842		 *    } );
25843		 */
25844		this._ = function ( sSelector, oOpts )
25845		{
25846			return this.api(true).rows( sSelector, oOpts ).data();
25847		};
25848
25849
25850		/**
25851		 * Create a DataTables Api instance, with the currently selected tables for
25852		 * the Api's context.
25853		 * @param {boolean} [traditional=false] Set the API instance's context to be
25854		 *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was
25855		 *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),
25856		 *   or if all tables captured in the jQuery object should be used.
25857		 * @return {DataTables.Api}
25858		 */
25859		this.api = function ( traditional )
25860		{
25861			return traditional ?
25862				new _Api(
25863					_fnSettingsFromNode( this[ _ext.iApiIndex ] )
25864				) :
25865				new _Api( this );
25866		};
25867
25868
25869		/**
25870		 * Add a single new row or multiple rows of data to the table. Please note
25871		 * that this is suitable for client-side processing only - if you are using
25872		 * server-side processing (i.e. "bServerSide": true), then to add data, you
25873		 * must add it to the data source, i.e. the server-side, through an Ajax call.
25874		 *  @param {array|object} data The data to be added to the table. This can be:
25875		 *    <ul>
25876		 *      <li>1D array of data - add a single row with the data provided</li>
25877		 *      <li>
258772D array of arrays - add multiple rows in a single call</li>
25878		 *      <li>object - data object when using <i>mData</i></li>
25879		 *      <li>array of objects - multiple data objects when using <i>mData</i></li>
25880		 *    </ul>
25881		 *  @param {bool} [redraw=true] redraw the table or not
25882		 *  @returns {array} An array of integers, representing the list of indexes in
25883		 *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
25884		 *    the table.
25885		 *  @dtopt API
25886		 *  @deprecated Since v1.10
25887		 *
25888		 *  @example
25889		 *    // Global var for counter
25890		 *    var giCount = 2;
25891		 *
25892		 *    $(document).ready(function() {
25893		 *      $('#example').dataTable();
25894		 *    } );
25895		 *
25896		 *    function fnClickAddRow() {
25897		 *      $('#example').dataTable().fnAddData( [
25898		 *        giCount+".1",
25899		 *        giCount+".2",
25900		 *        giCount+".3",
25901		 *        giCount+".4" ]
25902		 *      );
25903		 *
25904		 *      giCount++;
25905		 *    }
25906		 */
25907		this.fnAddData = function( data, redraw )
25908		{
25909			var api = this.api( true );
25910
25911			/* Check if we want to add multiple rows or not */
25912			var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
25913				api.rows.add( data ) :
25914				api.row.add( data );
25915
25916			if ( redraw === undefined || redraw ) {
25917				api.draw();
25918			}
25919
25920			return rows.flatten().toArray();
25921		};
25922
25923
25924		/**
25925		 * This function will make DataTables recalculate the column sizes, based on the data
25926		 * contained in the table and the sizes applied to the columns (in the DOM, CSS or
25927		 * through the sWidth parameter). This can be useful when the width of the table's
25928		 * parent element changes (for example a window resize).
25929		 *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
25930		 *  @dtopt API
25931		 *  @deprecated Since v1.10
25932		 *
25933		 *  @example
25934		 *    $(document).ready(function() {
25935		 *      var oTable = $('#example').dataTable( {
25936		 *        "sScrollY": "200px",
25937		 *        "bPaginate": false
25938		 *      } );
25939		 *
25940		 *      $(window).bind('resize', function () {
25941		 *        oTable.fnAdjustColumnSizing();
25942		 *      } );
25943		 *    } );
25944		 */
25945		this.fnAdjustColumnSizing = function ( bRedraw )
25946		{
25947			var api = this.api( true ).columns.adjust();
25948			var settings = api.settings()[0];
25949			var scroll = settings.oScroll;
25950
25951			if ( bRedraw === undefined || bRedraw ) {
25952				api.draw( false );
25953			}
25954			else if ( scroll.sX !== "" || scroll.sY !== "" ) {
25955				/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
25956				_fnScrollDraw( settings );
25957			}
25958		};
25959
25960
25961		/**
25962		 * Quickly and simply clear a table
25963		 *  @param {bool} [bRedraw=true] redraw the table or not
25964		 *  @dtopt API
25965		 *  @deprecated Since v1.10
25966		 *
25967		 *  @example
25968		 *    $(document).ready(function() {
25969		 *      var oTable = $('#example').dataTable();
25970		 *
25971		 *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
25972		 *      oTable.fnClearTable();
25973		 *    } );
25974		 */
25975		this.fnClearTable = function( bRedraw )
25976		{
25977			var api = this.api( true ).clear();
25978
25979			if ( bRedraw === undefined || bRedraw ) {
25980				api.draw();
25981			}
25982		};
25983
25984
25985		/**
25986		 * The exact opposite of 'opening' a row, this function will close any rows which
25987		 * are currently 'open'.
25988		 *  @param {node} nTr the table row to 'close'
25989		 *  @returns {int} 0 on success, or 1 if failed (can't find the row)
25990		 *  @dtopt API
25991		 *  @deprecated Since v1.10
25992		 *
25993		 *  @example
25994		 *    $(document).ready(function() {
25995		 *      var oTable;
25996		 *
25997		 *      // 'open' an information row when a row is clicked on
25998		 *      $('#example tbody tr').click( function () {
25999		 *        if ( oTable.fnIsOpen(this) ) {
26000		 *          oTable.fnClose( this );
26001		 *        } else {
26002		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
26003		 *        }
26004		 *      } );
26005		 *
26006		 *      oTable = $('#example').dataTable();
26007		 *    } );
26008		 */
26009		this.fnClose = function( nTr )
26010		{
26011			this.api( true ).row( nTr ).child.hide();
26012		};
26013
26014
26015		/**
26016		 * Remove a row for the table
26017		 *  @param {mixed} target The index of the row from aoData to be deleted, or
26018		 *    the TR element you want to delete
vendor: 20,482 bytes, lines 26019-26690
26019		 *  @param {function|null} [callBack] Callback function
26020		 *  @param {bool} [redraw=true] Redraw the table or not
26021		 *  @returns {array} The row that was deleted
26022		 *  @dtopt API
26023		 *  @deprecated Since v1.10
26024		 *
26025		 *  @example
26026		 *    $(document).ready(function() {
26027		 *      var oTable = $('#example').dataTable();
26028		 *
26029		 *      // Immediately remove the first row
26030		 *      oTable.fnDeleteRow( 0 );
26031		 *    } );
26032		 */
26033		this.fnDeleteRow = function( target, callback, redraw )
26034		{
26035			var api = this.api( true );
26036			var rows = api.rows( target );
26037			var settings = rows.settings()[0];
26038			var data = settings.aoData[ rows[0][0] ];
26039
26040			rows.remove();
26041
26042			if ( callback ) {
26043				callback.call( this, settings, data );
26044			}
26045
26046			if ( redraw === undefined || redraw ) {
26047				api.draw();
26048			}
26049
26050			return data;
26051		};
26052
26053
26054		/**
26055		 * Restore the table to it's original state in the DOM by removing all of DataTables
26056		 * enhancements, alterations to the DOM structure of the table and event listeners.
26057		 *  @param {boolean} [remove=false] Completely remove the table from the DOM
26058		 *  @dtopt API
26059		 *  @deprecated Since v1.10
26060		 *
26061		 *  @example
26062		 *    $(document).ready(function() {
26063		 *      // This example is fairly pointless in reality, but shows how fnDestroy can be used
26064		 *      var oTable = $('#example').dataTable();
26065		 *      oTable.fnDestroy();
26066		 *    } );
26067		 */
26068		this.fnDestroy = function ( remove )
26069		{
26070			this.api( true ).destroy( remove );
26071		};
26072
26073
26074		/**
26075		 * Redraw the table
26076		 *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
26077		 *  @dtopt API
26078		 *  @deprecated Since v1.10
26079		 *
26080		 *  @example
26081		 *    $(document).ready(function() {
26082		 *      var oTable = $('#example').dataTable();
26083		 *
26084		 *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
26085		 *      oTable.fnDraw();
26086		 *    } );
26087		 */
26088		this.fnDraw = function( complete )
26089		{
26090			// Note that this isn't an exact match to the old call to _fnDraw - it takes
26091			// into account the new data, but can hold position.
26092			this.api( true ).draw( complete );
26093		};
26094
26095
26096		/**
26097		 * Filter the input based on data
26098		 *  @param {string} sInput String to filter the table on
26099		 *  @param {int|null} [iColumn] Column to limit filtering to
26100		 *  @param {bool} [bRegex=false] Treat as regular expression or not
26101		 *  @param {bool} [bSmart=true] Perform smart filtering or not
26102		 *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
26103		 *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
26104		 *  @dtopt API
26105		 *  @deprecated Since v1.10
26106		 *
26107		 *  @example
26108		 *    $(document).ready(function() {
26109		 *      var oTable = $('#example').dataTable();
26110		 *
26111		 *      // Sometime later - filter...
26112		 *      oTable.fnFilter( 'test string' );
26113		 *    } );
26114		 */
26115		this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
26116		{
26117			var api = this.api( true );
26118
26119			if ( iColumn === null || iColumn === undefined ) {
26120				api.search( sInput, bRegex, bSmart, bCaseInsensitive );
26121			}
26122			else {
26123				api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
26124			}
26125
26126			api.draw();
26127		};
26128
26129
26130		/**
26131		 * Get the data for the whole table, an individual row or an individual cell based on the
26132		 * provided parameters.
26133		 *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
26134		 *    a TR node then the data source for the whole row will be returned. If given as a
26135		 *    TD/TH cell node then iCol will be automatically calculated and the data for the
26136		 *    cell returned. If given as an integer, then this is treated as the aoData internal
26137		 *    data index for the row (see fnGetPosition) and the data for that row used.
26138		 *  @param {int} [col] Optional column index that you want the data of.
26139		 *  @returns {array|object|string} If mRow is undefined, then the data for all rows is
26140		 *    returned. If mRow is defined, just data for that row, and is iCol is
26141		 *    defined, only data for the designated cell is returned.
26142		 *  @dtopt API
26143		 *  @deprecated Since v1.10
26144		 *
26145		 *  @example
26146		 *    // Row data
26147		 *    $(document).ready(function() {
26148		 *      oTable = $('#example').dataTable();
26149		 *
26150		 *      oTable.$('tr').click( function () {
26151		 *        var data = oTable.fnGetData( this );
26152		 *        // ... do something with the array / object of data for the row
26153		 *      } );
26154		 *    } );
26155		 *
26156		 *  @example
26157		 *    // Individual cell data
26158		 *    $(document).ready(function() {
26159		 *      oTable = $('#example').dataTable();
26160		 *
26161		 *      oTable.$('td').click( function () {
26162		 *        var sData = oTable.fnGetData( this );
26163		 *        alert( 'The cell clicked on had the value of '+sData );
26164		 *      } );
26165		 *    } );
26166		 */
26167		this.fnGetData = function( src, col )
26168		{
26169			var api = this.api( true );
26170
26171			if ( src !== undefined ) {
26172				var type = src.nodeName ? src.nodeName.toLowerCase() : '';
26173
26174				return col !== undefined || type == 'td' || type == 'th' ?
26175					api.cell( src, col ).data() :
26176					api.row( src ).data() || null;
26177			}
26178
26179			return api.data().toArray();
26180		};
26181
26182
26183		/**
26184		 * Get an array of the TR nodes that are used in the table's body. Note that you will
26185		 * typically want to use the '$' API method in preference to this as it is more
26186		 * flexible.
26187		 *  @param {int} [iRow] Optional row index for the TR element you want
26188		 *  @returns {array|node} If iRow is undefined, returns an array of all TR elements
26189		 *    in the table's body, or iRow is defined, just the TR element requested.
26190		 *  @dtopt API
26191		 *  @deprecated Since v1.10
26192		 *
26193		 *  @example
26194		 *    $(document).ready(function() {
26195		 *      var oTable = $('#example').dataTable();
26196		 *
26197		 *      // Get the nodes from the table
26198		 *      var nNodes = oTable.fnGetNodes( );
26199		 *    } );
26200		 */
26201		this.fnGetNodes = function( iRow )
26202		{
26203			var api = this.api( true );
26204
26205			return iRow !== undefined ?
26206				api.row( iRow ).node() :
26207				api.rows().nodes().flatten().toArray();
26208		};
26209
26210
26211		/**
26212		 * Get the array indexes of a particular cell from it's DOM element
26213		 * and column index including hidden columns
26214		 *  @param {node} node this can either be a TR, TD or TH in the table's body
26215		 *  @returns {int} If nNode is given as a TR, then a single index is returned, or
26216		 *    if given as a cell, an array of [row index, column index (visible),
26217		 *    column index (all)] is given.
26218		 *  @dtopt API
26219		 *  @deprecated Since v1.10
26220		 *
26221		 *  @example
26222		 *    $(document).ready(function() {
26223		 *      $('#example tbody td').click( function () {
26224		 *        // Get the position of the current data from the node
26225		 *        var aPos = oTable.fnGetPosition( this );
26226		 *
26227		 *        // Get the data array for this row
26228		 *        var aData = oTable.fnGetData( aPos[0] );
26229		 *
26230		 *        // Update the data array and return the value
26231		 *        aData[ aPos[1] ] = 'clicked';
26232		 *        this.innerHTML = 'clicked';
26233		 *      } );
26234		 *
26235		 *      // Init DataTables
26236		 *      oTable = $('#example').dataTable();
26237		 *    } );
26238		 */
26239		this.fnGetPosition = function( node )
26240		{
26241			var api = this.api( true );
26242			var nodeName = node.nodeName.toUpperCase();
26243
26244			if ( nodeName == 'TR' ) {
26245				return api.row( node ).index();
26246			}
26247			else if ( nodeName == 'TD' || nodeName == 'TH' ) {
26248				var cell = api.cell( node ).index();
26249
26250				return [
26251					cell.row,
26252					cell.columnVisible,
26253					cell.column
26254				];
26255			}
26256			return null;
26257		};
26258
26259
26260		/**
26261		 * Check to see if a row is 'open' or not.
26262		 *  @param {node} nTr the table row to check
26263		 *  @returns {boolean} true if the row is currently open, false otherwise
26264		 *  @dtopt API
26265		 *  @deprecated Since v1.10
26266		 *
26267		 *  @example
26268		 *    $(document).ready(function() {
26269		 *      var oTable;
26270		 *
26271		 *      // 'open' an information row when a row is clicked on
26272		 *      $('#example tbody tr').click( function () {
26273		 *        if ( oTable.fnIsOpen(this) ) {
26274		 *          oTable.fnClose( this );
26275		 *        } else {
26276		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
26277		 *        }
26278		 *      } );
26279		 *
26280		 *      oTable = $('#example').dataTable();
26281		 *    } );
26282		 */
26283		this.fnIsOpen = function( nTr )
26284		{
26285			return this.api( true ).row( nTr ).child.isShown();
26286		};
26287
26288
26289		/**
26290		 * This function will place a new row directly after a row which is currently
26291		 * on display on the page, with the HTML contents that is passed into the
26292		 * function. This can be used, for example, to ask for confirmation that a
26293		 * particular record should be deleted.
26294		 *  @param {node} nTr The table row to 'open'
26295		 *  @param {string|node|jQuery} mHtml The HTML to put into the row
26296		 *  @param {string} sClass Class to give the new TD cell
26297		 *  @returns {node} The row opened. Note that if the table row passed in as the
26298		 *    first parameter, is not found in the table, this method will silently
26299		 *    return.
26300		 *  @dtopt API
26301		 *  @deprecated Since v1.10
26302		 *
26303		 *  @example
26304		 *    $(document).ready(function() {
26305		 *      var oTable;
26306		 *
26307		 *      // 'open' an information row when a row is clicked on
26308		 *      $('#example tbody tr').click( function () {
26309		 *        if ( oTable.fnIsOpen(this) ) {
26310		 *          oTable.fnClose( this );
26311		 *        } else {
26312		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
26313		 *        }
26314		 *      } );
26315		 *
26316		 *      oTable = $('#example').dataTable();
26317		 *    } );
26318		 */
26319		this.fnOpen = function( nTr, mHtml, sClass )
26320		{
26321			return this.api( true )
26322				.row( nTr )
26323				.child( mHtml, sClass )
26324				.show()
26325				.child()[0];
26326		};
26327
26328
26329		/**
26330		 * Change the pagination - provides the internal logic for pagination in a simple API
26331		 * function. With this function you can have a DataTables table go to the next,
26332		 * previous, first or last pages.
26333		 *  @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
26334		 *    or page number to jump to (integer), note that page 0 is the first page.
26335		 *  @param {bool} [bRedraw=true] Redraw the table or not
26336		 *  @dtopt API
26337		 *  @deprecated Since v1.10
26338		 *
26339		 *  @example
26340		 *    $(document).ready(function() {
26341		 *      var oTable = $('#example').dataTable();
26342		 *      oTable.fnPageChange( 'next' );
26343		 *    } );
26344		 */
26345		this.fnPageChange = function ( mAction, bRedraw )
26346		{
26347			var api = this.api( true ).page( mAction );
26348
26349			if ( bRedraw === undefined || bRedraw ) {
26350				api.draw(false);
26351			}
26352		};
26353
26354
26355		/**
26356		 * Show a particular column
26357		 *  @param {int} iCol The column whose display should be changed
26358		 *  @param {bool} bShow Show (true) or hide (false) the column
26359		 *  @param {bool} [bRedraw=true] Redraw the table or not
26360		 *  @dtopt API
26361		 *  @deprecated Since v1.10
26362		 *
26363		 *  @example
26364		 *    $(document).ready(function() {
26365		 *      var oTable = $('#example').dataTable();
26366		 *
26367		 *      // Hide the second column after initialisation
26368		 *      oTable.fnSetColumnVis( 1, false );
26369		 *    } );
26370		 */
26371		this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
26372		{
26373			var api = this.api( true ).column( iCol ).visible( bShow );
26374
26375			if ( bRedraw === undefined || bRedraw ) {
26376				api.columns.adjust().draw();
26377			}
26378		};
26379
26380
26381		/**
26382		 * Get the settings for a particular table for external manipulation
26383		 *  @returns {object} DataTables settings object. See
26384		 *    {@link DataTable.models.oSettings}
26385		 *  @dtopt API
26386		 *  @deprecated Since v1.10
26387		 *
26388		 *  @example
26389		 *    $(document).ready(function() {
26390		 *      var oTable = $('#example').dataTable();
26391		 *      var oSettings = oTable.fnSettings();
26392		 *
26393		 *      // Show an example parameter from the settings
26394		 *      alert( oSettings._iDisplayStart );
26395		 *    } );
26396		 */
26397		this.fnSettings = function()
26398		{
26399			return _fnSettingsFromNode( this[_ext.iApiIndex] );
26400		};
26401
26402
26403		/**
26404		 * Sort the table by a particular column
26405		 *  @param {int} iCol the data index to sort on. Note that this will not match the
26406		 *    'display index' if you have hidden data entries
26407		 *  @dtopt API
26408		 *  @deprecated Since v1.10
26409		 *
26410		 *  @example
26411		 *    $(document).ready(function() {
26412		 *      var oTable = $('#example').dataTable();
26413		 *
26414		 *      // Sort immediately with columns 0 and 1
26415		 *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
26416		 *    } );
26417		 */
26418		this.fnSort = function( aaSort )
26419		{
26420			this.api( true ).order( aaSort ).draw();
26421		};
26422
26423
26424		/**
26425		 * Attach a sort listener to an element for a given column
26426		 *  @param {node} nNode the element to attach the sort listener to
26427		 *  @param {int} iColumn the column that a click on this node will sort on
26428		 *  @param {function} [fnCallback] callback function when sort is run
26429		 *  @dtopt API
26430		 *  @deprecated Since v1.10
26431		 *
26432		 *  @example
26433		 *    $(document).ready(function() {
26434		 *      var oTable = $('#example').dataTable();
26435		 *
26436		 *      // Sort on column 1, when 'sorter' is clicked on
26437		 *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
26438		 *    } );
26439		 */
26440		this.fnSortListener = function( nNode, iColumn, fnCallback )
26441		{
26442			this.api( true ).order.listener( nNode, iColumn, fnCallback );
26443		};
26444
26445
26446		/**
26447		 * Update a table cell or row - this method will accept either a single value to
26448		 * update the cell with, an array of values with one element for each column or
26449		 * an object in the same format as the original data source. The function is
26450		 * self-referencing in order to make the multi column updates easier.
26451		 *  @param {object|array|string} mData Data to update the cell/row with
26452		 *  @param {node|int} mRow TR element you want to update or the aoData index
26453		 *  @param {int} [iColumn] The column to update, give as null or undefined to
26454		 *    update a whole row.
26455		 *  @param {bool} [bRedraw=true] Redraw the table or not
26456		 *  @param {bool} [bAction=true] Perform pre-draw actions or not
26457		 *  @returns {int} 0 on success, 1 on error
26458		 *  @dtopt API
26459		 *  @deprecated Since v1.10
26460		 *
26461		 *  @example
26462		 *    $(document).ready(function() {
26463		 *      var oTable = $('#example').dataTable();
26464		 *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
26465		 *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
26466		 *    } );
26467		 */
26468		this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
26469		{
26470			var api = this.api( true );
26471
26472			if ( iColumn === undefined || iColumn === null ) {
26473				api.row( mRow ).data( mData );
26474			}
26475			else {
26476				api.cell( mRow, iColumn ).data( mData );
26477			}
26478
26479			if ( bAction === undefined || bAction ) {
26480				api.columns.adjust();
26481			}
26482
26483			if ( bRedraw === undefined || bRedraw ) {
26484				api.draw();
26485			}
26486			return 0;
26487		};
26488
26489
26490		/**
26491		 * Provide a common method for plug-ins to check the version of DataTables being used, in order
26492		 * to ensure compatibility.
26493		 *  @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
26494		 *    formats "X" and "X.Y" are also acceptable.
26495		 *  @returns {boolean} true if this version of DataTables is greater or equal to the required
26496		 *    version, or false if this version of DataTales is not suitable
26497		 *  @method
26498		 *  @dtopt API
26499		 *  @deprecated Since v1.10
26500		 *
26501		 *  @example
26502		 *    $(document).ready(function() {
26503		 *      var oTable = $('#example').dataTable();
26504		 *      alert( oTable.fnVersionCheck( '1.9.0' ) );
26505		 *    } );
26506		 */
26507		this.fnVersionCheck = _ext.fnVersionCheck;
26508
26509
26510		var _that = this;
26511		var emptyInit = options === undefined;
26512		var len = this.length;
26513
26514		if ( emptyInit ) {
26515			options = {};
26516		}
26517
26518		this.oApi = this.internal = _ext.internal;
26519
26520		// Extend with old style plug-in API methods
26521		for ( var fn in DataTable.ext.internal ) {
26522			if ( fn ) {
26523				this[fn] = _fnExternApiFunc(fn);
26524			}
26525		}
26526
26527		this.each(function() {
26528			// For each initialisation we want to give it a clean initialisation
26529			// object that can be bashed around
26530			var o = {};
26531			var oInit = len > 1 ? // optimisation for single table case
26532				_fnExtend( o, options, true ) :
26533				options;
26534
26535			/*global oInit,_that,emptyInit*/
26536			var i=0, iLen, j, jLen, k, kLen;
26537			var sId = this.getAttribute( 'id' );
26538			var bInitHandedOff = false;
26539			var defaults = DataTable.defaults;
26540			var $this = $(this);
26541
26542
26543			/* Sanity check */
26544			if ( this.nodeName.toLowerCase() != 'table' )
26545			{
26546				_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
26547				return;
26548			}
26549
26550			/* Backwards compatibility for the defaults */
26551			_fnCompatOpts( defaults );
26552			_fnCompatCols( defaults.column );
26553
26554			/* Convert the camel-case defaults to Hungarian */
26555			_fnCamelToHungarian( defaults, defaults, true );
26556			_fnCamelToHungarian( defaults.column, defaults.column, true );
26557
26558			/* Setting up the initialisation object */
26559			_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
26560
26561
26562
26563			/* Check to see if we are re-initialising a table */
26564			var allSettings = DataTable.settings;
26565			for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
26566			{
26567				var s = allSettings[i];
26568
26569				/* Base check on table node */
26570				if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
26571				{
26572					var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
26573					var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
26574
26575					if ( emptyInit || bRetrieve )
26576					{
26577						return s.oInstance;
26578					}
26579					else if ( bDestroy )
26580					{
26581						s.oInstance.fnDestroy();
26582						break;
26583					}
26584					else
26585					{
26586						_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
26587						return;
26588					}
26589				}
26590
26591				/* If the element we are initialising has the same ID as a table which was previously
26592				 * initialised, but the table nodes don't match (from before) then we destroy the old
26593				 * instance by simply deleting it. This is under the assumption that the table has been
26594				 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
26595				 */
26596				if ( s.sTableId == this.id )
26597				{
26598					allSettings.splice( i, 1 );
26599					break;
26600				}
26601			}
26602
26603			/* Ensure the table has an ID - required for accessibility */
26604			if ( sId === null || sId === "" )
26605			{
26606				sId = "DataTables_Table_"+(DataTable.ext._unique++);
26607				this.id = sId;
26608			}
26609
26610			/* Create the settings object for this table and set some of the default parameters */
26611			var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
26612				"sDestroyWidth": $this[0].style.width,
26613				"sInstance":     sId,
26614				"sTableId":      sId
26615			} );
26616			oSettings.nTable = this;
26617			oSettings.oApi   = _that.internal;
26618			oSettings.oInit  = oInit;
26619
26620			allSettings.push( oSettings );
26621
26622			// Need to add the instance after the instance after the settings object has been added
26623			// to the settings array, so we can self reference the table instance if more than one
26624			oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
26625
26626			// Backwards compatibility, before we apply all the defaults
26627			_fnCompatOpts( oInit );
26628
26629			if ( oInit.oLanguage )
26630			{
26631				_fnLanguageCompat( oInit.oLanguage );
26632			}
26633
26634			// If the length menu is given, but the init display length is not, use the length menu
26635			if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
26636			{
26637				oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
26638					oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
26639			}
26640
26641			// Apply the defaults and init options to make a single init object will all
26642			// options defined from defaults and instance options.
26643			oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
26644
26645
26646			// Map the initialisation options onto the settings object
26647			_fnMap( oSettings.oFeatures, oInit, [
26648				"bPaginate",
26649				"bLengthChange",
26650				"bFilter",
26651				"bSort",
26652				"bSortMulti",
26653				"bInfo",
26654				"bProcessing",
26655				"bAutoWidth",
26656				"bSortClasses",
26657				"bServerSide",
26658				"bDeferRender"
26659			] );
26660			_fnMap( oSettings, oInit, [
26661				"asStripeClasses",
26662				"ajax",
26663				"fnServerData",
26664				"fnFormatNumber",
26665				"sServerMethod",
26666				"aaSorting",
26667				"aaSortingFixed",
26668				"aLengthMenu",
26669				"sPaginationType",
26670				"sAjaxSource",
26671				"sAjaxDataProp",
26672				"iStateDuration",
26673				"sDom",
26674				"bSortCellsTop",
26675				"iTabIndex",
26676				"fnStateLoadCallback",
26677				"fnStateSaveCallback",
26678				"renderer",
26679				"searchDelay",
26680				"rowId",
26681				[ "iCookieDuration", "iStateDuration" ], // backwards compat
26682				[ "oSearch", "oPreviousSearch" ],
26683				[ "aoSearchCols", "aoPreSearchCols" ],
26684				[ "iDisplayLength", "_iDisplayLength" ],
26685				[ "bJQueryUI", "bJUI" ]
26686			] );
26687			_fnMap( oSettings.oScroll, oInit, [
26688				[ "sScrollX", "sX" ],
26689				[ "sScrollXInner", "sXInner" ],
26690				[ "sScrollY", "sY" ],
26691				[ "bScrollCollapse", "bCollapse" ]
26692			] );
26693			_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
26694
26695			/* Callback functions which are array driven */
26696			_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );
26697			_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );
26698			_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );
26699			_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );
26700			_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );
26701			_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );
26702			_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );
26703			_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );
26704			_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );
26705			_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );
26706			_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );
26707
26708			oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
26709
26710			/* Browser support detection */
26711			_fnBrowserDetect( oSettings );
26712
26713			var oClasses = oSettings.oClasses;
26714
26715			// @todo Remove in 1.11
26716			if ( oInit.bJQueryUI )
26717			{
26718				/* Use the JUI classes object for display. You could clone the oStdClasses object if
26719				 * you want to have multiple tables with multiple independent classes
26720				 */
26721				$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
26722
26723				if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
26724				{
26725					/* Set the DOM to use a layout suitable for jQuery UI's theming */
26726					oSettings.sDom = '<"H"lfr>t<"F"ip>';
26727				}
26728
26729				if ( ! oSettings.renderer ) {
26730					oSettings.renderer = 'jqueryui';
26731				}
26732				else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
26733					oSettings.renderer.header = 'jqueryui';
26734				}
26735			}
26736			else
26737			{
26738				$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
26739			}
26740			$this.addClass( oClasses.sTable );
26741
26742
26743			if ( oSettings.iInitDisplayStart === undefined )
26744			{
26745				/* Display start point, taking into account the save saving */
26746				oSettings.iInitDisplayStart = oInit.iDisplayStart;
26747				oSettings._iDisplayStart = oInit.iDisplayStart;
26748			}
26749
26750			if ( oInit.iDeferLoading !== null )
26751			{
26752				oSettings.bDeferLoading = true;
26753				var tmp = $.isArray( oInit.iDeferLoading );
26754				oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
26755				oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
26756			}
26757
26758			/* Language definitions */
26759			var oLanguage = oSettings.oLanguage;
26760			$.extend( true, oLanguage, oInit.oLanguage );
26761
26762			if ( oLanguage.sUrl !== "" )
26763			{
26764				/* Get the language definitions from a file - because this Ajax call makes the language
26765				 * get async to the remainder of this function we use bInitHandedOff to indicate that
26766				 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
26767				 */
26768				$.ajax( {
26769					dataType: 'json',
26770					url: oLanguage.sUrl,
26771					success: function ( json ) {
26772						_fnLanguageCompat( json );
26773						_fnCamelToHungarian( defaults.oLanguage, json );
26774						$.extend( true, oLanguage, json );
26775						_fnInitialise( oSettings );
26776					},
26777					error: function () {
26778						// Error occurred loading language file, continue on as best we can
26779						_fnInitialise( oSettings );
26780					}
26781				} );
26782				bInitHandedOff = true;
26783			}
26784
26785			/*
26786			 * Stripes
26787			 */
26788			if ( oInit.asStripeClasses === null )
26789			{
26790				oSettings.asStripeClasses =[
26791					oClasses.sStripeOdd,
26792					oClasses.sStripeEven
26793				];
26794			}
26795
26796			/* Remove row stripe classes if they are already on the table row */
26797			var stripeClasses = oSettings.asStripeClasses;
26798			var rowOne = $this.children('tbody').find('tr').eq(0);
26799			if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
26800				return rowOne.hasClass(el);
26801			} ) ) !== -1 ) {
26802				$('tbody tr', this).removeClass( stripeClasses.join(' ') );
26803				oSettings.asDestroyStripes = stripeClasses.slice();
26804			}
26805
26806			/*
26807			 * Columns
26808			 * See if we should load columns automatically or use defined ones
26809			 */
26810			var anThs = [];
26811			var aoColumnsInit;
26812			var nThead = this.getElementsByTagName('thead');
26813			if ( nThead.length !== 0 )
26814			{
26815				_fnDetectHeader( oSettings.aoHeader, nThead[0] );
26816				anThs = _fnGetUniqueThs( oSettings );
26817			}
26818
26819			/* If not given a column array, generate one with nulls */
26820			if ( oInit.aoColumns === null )
26821			{
26822				aoColumnsInit = [];
26823				for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
26824				{
26825					aoColumnsInit.push( null );
26826				}
26827			}
26828			else
26829			{
vendor: 46,720 bytes, lines 26830-28511
26830				aoColumnsInit = oInit.aoColumns;
26831			}
26832
26833			/* Add the columns */
26834			for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
26835			{
26836				_fnAddColumn( oSettings, anThs ? anThs[i] : null );
26837			}
26838
26839			/* Apply the column definitions */
26840			_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
26841				_fnColumnOptions( oSettings, iCol, oDef );
26842			} );
26843
26844			/* HTML5 attribute detection - build an mData object automatically if the
26845			 * attributes are found
26846			 */
26847			if ( rowOne.length ) {
26848				var a = function ( cell, name ) {
26849					return cell.getAttribute( 'data-'+name ) !== null ? name : null;
26850				};
26851
26852				$( rowOne[0] ).children('th, td').each( function (i, cell) {
26853					var col = oSettings.aoColumns[i];
26854
26855					if ( col.mData === i ) {
26856						var sort = a( cell, 'sort' ) || a( cell, 'order' );
26857						var filter = a( cell, 'filter' ) || a( cell, 'search' );
26858
26859						if ( sort !== null || filter !== null ) {
26860							col.mData = {
26861								_:      i+'.display',
26862								sort:   sort !== null   ? i+'.@data-'+sort   : undefined,
26863								type:   sort !== null   ? i+'.@data-'+sort   : undefined,
26864								filter: filter !== null ? i+'.@data-'+filter : undefined
26865							};
26866
26867							_fnColumnOptions( oSettings, i );
26868						}
26869					}
26870				} );
26871			}
26872
26873			var features = oSettings.oFeatures;
26874
26875			/* Must be done after everything which can be overridden by the state saving! */
26876			if ( oInit.bStateSave )
26877			{
26878				features.bStateSave = true;
26879				_fnLoadState( oSettings, oInit );
26880				_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
26881			}
26882
26883
26884			/*
26885			 * Sorting
26886			 * @todo For modularisation (1.11) this needs to do into a sort start up handler
26887			 */
26888
26889			// If aaSorting is not defined, then we use the first indicator in asSorting
26890			// in case that has been altered, so the default sort reflects that option
26891			if ( oInit.aaSorting === undefined )
26892			{
26893				var sorting = oSettings.aaSorting;
26894				for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
26895				{
26896					sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
26897				}
26898			}
26899
26900			/* Do a first pass on the sorting classes (allows any size changes to be taken into
26901			 * account, and also will apply sorting disabled classes if disabled
26902			 */
26903			_fnSortingClasses( oSettings );
26904
26905			if ( features.bSort )
26906			{
26907				_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
26908					if ( oSettings.bSorted ) {
26909						var aSort = _fnSortFlatten( oSettings );
26910						var sortedColumns = {};
26911
26912						$.each( aSort, function (i, val) {
26913							sortedColumns[ val.src ] = val.dir;
26914						} );
26915
26916						_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
26917						_fnSortAria( oSettings );
26918					}
26919				} );
26920			}
26921
26922			_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
26923				if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
26924					_fnSortingClasses( oSettings );
26925				}
26926			}, 'sc' );
26927
26928
26929			/*
26930			 * Final init
26931			 * Cache the header, body and footer as required, creating them if needed
26932			 */
26933
26934			// Work around for Webkit bug 83867 - store the caption-side before removing from doc
26935			var captions = $this.children('caption').each( function () {
26936				this._captionSide = $this.css('caption-side');
26937			} );
26938
26939			var thead = $this.children('thead');
26940			if ( thead.length === 0 )
26941			{
26942				thead = $('<thead/>').appendTo(this);
26943			}
26944			oSettings.nTHead = thead[0];
26945
26946			var tbody = $this.children('tbody');
26947			if ( tbody.length === 0 )
26948			{
26949				tbody = $('<tbody/>').appendTo(this);
26950			}
26951			oSettings.nTBody = tbody[0];
26952
26953			var tfoot = $this.children('tfoot');
26954			if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
26955			{
26956				// If we are a scrolling table, and no footer has been given, then we need to create
26957				// a tfoot element for the caption element to be appended to
26958				tfoot = $('<tfoot/>').appendTo(this);
26959			}
26960
26961			if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
26962				$this.addClass( oClasses.sNoFooter );
26963			}
26964			else if ( tfoot.length > 0 ) {
26965				oSettings.nTFoot = tfoot[0];
26966				_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
26967			}
26968
26969			/* Check if there is data passing into the constructor */
26970			if ( oInit.aaData )
26971			{
26972				for ( i=0 ; i<oInit.aaData.length ; i++ )
26973				{
26974					_fnAddData( oSettings, oInit.aaData[ i ] );
26975				}
26976			}
26977			else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
26978			{
26979				/* Grab the data from the page - only do this when deferred loading or no Ajax
26980				 * source since there is no point in reading the DOM data if we are then going
26981				 * to replace it with Ajax data
26982				 */
26983				_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
26984			}
26985
26986			/* Copy the data index array */
26987			oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
26988
26989			/* Initialisation complete - table can be drawn */
26990			oSettings.bInitialised = true;
26991
26992			/* Check if we need to initialise the table (it might not have been handed off to the
26993			 * language processor)
26994			 */
26995			if ( bInitHandedOff === false )
26996			{
26997				_fnInitialise( oSettings );
26998			}
26999		} );
27000		_that = null;
27001		return this;
27002	};
27003
27004
27005	/*
27006	 * It is useful to have variables which are scoped locally so only the
27007	 * DataTables functions can access them and they don't leak into global space.
27008	 * At the same time these functions are often useful over multiple files in the
27009	 * core and API, so we list, or at least document, all variables which are used
27010	 * by DataTables as private variables here. This also ensures that there is no
27011	 * clashing of variable names and that they can easily referenced for reuse.
27012	 */
27013
27014
27015	// Defined else where
27016	//  _selector_run
27017	//  _selector_opts
27018	//  _selector_first
27019	//  _selector_row_indexes
27020
27021	var _ext; // DataTable.ext
27022	var _Api; // DataTable.Api
27023	var _api_register; // DataTable.Api.register
27024	var _api_registerPlural; // DataTable.Api.registerPlural
27025
27026	var _re_dic = {};
27027	var _re_new_lines = /[\r\n]/g;
27028	var _re_html = /<.*?>/g;
27029	var _re_date_start = /^[\w\+\-]/;
27030	var _re_date_end = /[\w\+\-]$/;
27031
27032	// Escape regular expression special characters
27033	var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
27034
27035	// http://en.wikipedia.org/wiki/Foreign_exchange_market
27036	// - \u20BD - Russian ruble.
27037	// - \u20a9 - South Korean Won
27038	// - \u20BA - Turkish Lira
27039	// - \u20B9 - Indian Rupee
27040	// - R - Brazil (R$) and South Africa
27041	// - fr - Swiss Franc
27042	// - kr - Swedish krona, Norwegian krone and Danish krone
27043	// - \u2009 is thin space and \u202F is narrow no-break space, both used in many
27044	//   standards as thousands separators.
27045	var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
27046
27047
27048	var _empty = function ( d ) {
27049		return !d || d === true || d === '-' ? true : false;
27050	};
27051
27052
27053	var _intVal = function ( s ) {
27054		var integer = parseInt( s, 10 );
27055		return !isNaN(integer) && isFinite(s) ? integer : null;
27056	};
27057
27058	// Convert from a formatted number with characters other than `.` as the
27059	// decimal place, to a Javascript number
27060	var _numToDecimal = function ( num, decimalPoint ) {
27061		// Cache created regular expressions for speed as this function is called often
27062		if ( ! _re_dic[ decimalPoint ] ) {
27063			_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
27064		}
27065		return typeof num === 'string' && decimalPoint !== '.' ?
27066			num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
27067			num;
27068	};
27069
27070
27071	var _isNumber = function ( d, decimalPoint, formatted ) {
27072		var strType = typeof d === 'string';
27073
27074		// If empty return immediately so there must be a number if it is a
27075		// formatted string (this stops the string "k", or "kr", etc being detected
27076		// as a formatted number for currency
27077		if ( _empty( d ) ) {
27078			return true;
27079		}
27080
27081		if ( decimalPoint && strType ) {
27082			d = _numToDecimal( d, decimalPoint );
27083		}
27084
27085		if ( formatted && strType ) {
27086			d = d.replace( _re_formatted_numeric, '' );
27087		}
27088
27089		return !isNaN( parseFloat(d) ) && isFinite( d );
27090	};
27091
27092
27093	// A string without HTML in it can be considered to be HTML still
27094	var _isHtml = function ( d ) {
27095		return _empty( d ) || typeof d === 'string';
27096	};
27097
27098
27099	var _htmlNumeric = function ( d, decimalPoint, formatted ) {
27100		if ( _empty( d ) ) {
27101			return true;
27102		}
27103
27104		var html = _isHtml( d );
27105		return ! html ?
27106			null :
27107			_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
27108				true :
27109				null;
27110	};
27111
27112
27113	var _pluck = function ( a, prop, prop2 ) {
27114		var out = [];
27115		var i=0, ien=a.length;
27116
27117		// Could have the test in the loop for slightly smaller code, but speed
27118		// is essential here
27119		if ( prop2 !== undefined ) {
27120			for ( ; i<ien ; i++ ) {
27121				if ( a[i] && a[i][ prop ] ) {
27122					out.push( a[i][ prop ][ prop2 ] );
27123				}
27124			}
27125		}
27126		else {
27127			for ( ; i<ien ; i++ ) {
27128				if ( a[i] ) {
27129					out.push( a[i][ prop ] );
27130				}
27131			}
27132		}
27133
27134		return out;
27135	};
27136
27137
27138	// Basically the same as _pluck, but rather than looping over `a` we use `order`
27139	// as the indexes to pick from `a`
27140	var _pluck_order = function ( a, order, prop, prop2 )
27141	{
27142		var out = [];
27143		var i=0, ien=order.length;
27144
27145		// Could have the test in the loop for slightly smaller code, but speed
27146		// is essential here
27147		if ( prop2 !== undefined ) {
27148			for ( ; i<ien ; i++ ) {
27149				if ( a[ order[i] ][ prop ] ) {
27150					out.push( a[ order[i] ][ prop ][ prop2 ] );
27151				}
27152			}
27153		}
27154		else {
27155			for ( ; i<ien ; i++ ) {
27156				out.push( a[ order[i] ][ prop ] );
27157			}
27158		}
27159
27160		return out;
27161	};
27162
27163
27164	var _range = function ( len, start )
27165	{
27166		var out = [];
27167		var end;
27168
27169		if ( start === undefined ) {
27170			start = 0;
27171			end = len;
27172		}
27173		else {
27174			end = start;
27175			start = len;
27176		}
27177
27178		for ( var i=start ; i<end ; i++ ) {
27179			out.push( i );
27180		}
27181
27182		return out;
27183	};
27184
27185
27186	var _removeEmpty = function ( a )
27187	{
27188		var out = [];
27189
27190		for ( var i=0, ien=a.length ; i<ien ; i++ ) {
27191			if ( a[i] ) { // careful - will remove all falsy values!
27192				out.push( a[i] );
27193			}
27194		}
27195
27196		return out;
27197	};
27198
27199
27200	var _stripHtml = function ( d ) {
27201		return d.replace( _re_html, '' );
27202	};
27203
27204
27205	/**
27206	 * Find the unique elements in a source array.
27207	 *
27208	 * @param  {array} src Source array
27209	 * @return {array} Array of unique items
27210	 * @ignore
27211	 */
27212	var _unique = function ( src )
27213	{
27214		// A faster unique method is to use object keys to identify used values,
27215		// but this doesn't work with arrays or objects, which we must also
27216		// consider. See jsperf.com/compare-array-unique-versions/4 for more
27217		// information.
27218		var
27219			out = [],
27220			val,
27221			i, ien=src.length,
27222			j, k=0;
27223
27224		again: for ( i=0 ; i<ien ; i++ ) {
27225			val = src[i];
27226
27227			for ( j=0 ; j<k ; j++ ) {
27228				if ( out[j] === val ) {
27229					continue again;
27230				}
27231			}
27232
27233			out.push( val );
27234			k++;
27235		}
27236
27237		return out;
27238	};
27239
27240
27241	/**
27242	 * DataTables utility methods
27243	 *
27244	 * This namespace provides helper methods that DataTables uses internally to
27245	 * create a DataTable, but which are not exclusively used only for DataTables.
27246	 * These methods can be used by extension authors to save the duplication of
27247	 * code.
27248	 *
27249	 *  @namespace
27250	 */
27251	DataTable.util = {
27252		/**
27253		 * Throttle the calls to a function. Arguments and context are maintained
27254		 * for the throttled function.
27255		 *
27256		 * @param {function} fn Function to be called
27257		 * @param {integer} freq Call frequency in mS
27258		 * @return {function} Wrapped function
27259		 */
27260		throttle: function ( fn, freq ) {
27261			var
27262				frequency = freq !== undefined ? freq : 200,
27263				last,
27264				timer;
27265
27266			return function () {
27267				var
27268					that = this,
27269					now  = +new Date(),
27270					args = arguments;
27271
27272				if ( last && now < last + frequency ) {
27273					clearTimeout( timer );
27274
27275					timer = setTimeout( function () {
27276						last = undefined;
27277						fn.apply( that, args );
27278					}, frequency );
27279				}
27280				else {
27281					last = now;
27282					fn.apply( that, args );
27283				}
27284			};
27285		},
27286
27287
27288		/**
27289		 * Escape a string such that it can be used in a regular expression
27290		 *
27291		 *  @param {string} val string to escape
27292		 *  @returns {string} escaped string
27293		 */
27294		escapeRegex: function ( val ) {
27295			return val.replace( _re_escape_regex, '\\$1' );
27296		}
27297	};
27298
27299
27300
27301	/**
27302	 * Create a mapping object that allows camel case parameters to be looked up
27303	 * for their Hungarian counterparts. The mapping is stored in a private
27304	 * parameter called `_hungarianMap` which can be accessed on the source object.
27305	 *  @param {object} o
27306	 *  @memberof DataTable#oApi
27307	 */
27308	function _fnHungarianMap ( o )
27309	{
27310		var
27311			hungarian = 'a aa ai ao as b fn i m o s ',
27312			match,
27313			newKey,
27314			map = {};
27315
27316		$.each( o, function (key, val) {
27317			match = key.match(/^([^A-Z]+?)([A-Z])/);
27318
27319			if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
27320			{
27321				newKey = key.replace( match[0], match[2].toLowerCase() );
27322				map[ newKey ] = key;
27323
27324				if ( match[1] === 'o' )
27325				{
27326					_fnHungarianMap( o[key] );
27327				}
27328			}
27329		} );
27330
27331		o._hungarianMap = map;
27332	}
27333
27334
27335	/**
27336	 * Convert from camel case parameters to Hungarian, based on a Hungarian map
27337	 * created by _fnHungarianMap.
27338	 *  @param {object} src The model object which holds all parameters that can be
27339	 *    mapped.
27340	 *  @param {object} user The object to convert from camel case to Hungarian.
27341	 *  @param {boolean} force When set to `true`, properties which already have a
27342	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
27343	 *    won't be.
27344	 *  @memberof DataTable#oApi
27345	 */
27346	function _fnCamelToHungarian ( src, user, force )
27347	{
27348		if ( ! src._hungarianMap ) {
27349			_fnHungarianMap( src );
27350		}
27351
27352		var hungarianKey;
27353
27354		$.each( user, function (key, val) {
27355			hungarianKey = src._hungarianMap[ key ];
27356
27357			if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
27358			{
27359				// For objects, we need to buzz down into the object to copy parameters
27360				if ( hungarianKey.charAt(0) === 'o' )
27361				{
27362					// Copy the camelCase options over to the hungarian
27363					if ( ! user[ hungarianKey ] ) {
27364						user[ hungarianKey ] = {};
27365					}
27366					$.extend( true, user[hungarianKey], user[key] );
27367
27368					_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
27369				}
27370				else {
27371					user[hungarianKey] = user[ key ];
27372				}
27373			}
27374		} );
27375	}
27376
27377
27378	/**
27379	 * Language compatibility - when certain options are given, and others aren't, we
27380	 * need to duplicate the values over, in order to provide backwards compatibility
27381	 * with older language files.
27382	 *  @param {object} oSettings dataTables settings object
27383	 *  @memberof DataTable#oApi
27384	 */
27385	function _fnLanguageCompat( lang )
27386	{
27387		var defaults = DataTable.defaults.oLanguage;
27388		var zeroRecords = lang.sZeroRecords;
27389
27390		/* Backwards compatibility - if there is no sEmptyTable given, then use the same as
27391		 * sZeroRecords - assuming that is given.
27392		 */
27393		if ( ! lang.sEmptyTable && zeroRecords &&
27394			defaults.sEmptyTable === "No data available in table" )
27395		{
27396			_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
27397		}
27398
27399		/* Likewise with loading records */
27400		if ( ! lang.sLoadingRecords && zeroRecords &&
27401			defaults.sLoadingRecords === "Loading..." )
27402		{
27403			_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
27404		}
27405
27406		// Old parameter name of the thousands separator mapped onto the new
27407		if ( lang.sInfoThousands ) {
27408			lang.sThousands = lang.sInfoThousands;
27409		}
27410
27411		var decimal = lang.sDecimal;
27412		if ( decimal ) {
27413			_addNumericSort( decimal );
27414		}
27415	}
27416
27417
27418	/**
27419	 * Map one parameter onto another
27420	 *  @param {object} o Object to map
27421	 *  @param {*} knew The new parameter name
27422	 *  @param {*} old The old parameter name
27423	 */
27424	var _fnCompatMap = function ( o, knew, old ) {
27425		if ( o[ knew ] !== undefined ) {
27426			o[ old ] = o[ knew ];
27427		}
27428	};
27429
27430
27431	/**
27432	 * Provide backwards compatibility for the main DT options. Note that the new
27433	 * options are mapped onto the old parameters, so this is an external interface
27434	 * change only.
27435	 *  @param {object} init Object to map
27436	 */
27437	function _fnCompatOpts ( init )
27438	{
27439		_fnCompatMap( init, 'ordering',      'bSort' );
27440		_fnCompatMap( init, 'orderMulti',    'bSortMulti' );
27441		_fnCompatMap( init, 'orderClasses',  'bSortClasses' );
27442		_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
27443		_fnCompatMap( init, 'order',         'aaSorting' );
27444		_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );
27445		_fnCompatMap( init, 'paging',        'bPaginate' );
27446		_fnCompatMap( init, 'pagingType',    'sPaginationType' );
27447		_fnCompatMap( init, 'pageLength',    'iDisplayLength' );
27448		_fnCompatMap( init, 'searching',     'bFilter' );
27449
27450		// Boolean initialisation of x-scrolling
27451		if ( typeof init.sScrollX === 'boolean' ) {
27452			init.sScrollX = init.sScrollX ? '100%' : '';
27453		}
27454		if ( typeof init.scrollX === 'boolean' ) {
27455			init.scrollX = init.scrollX ? '100%' : '';
27456		}
27457
27458		// Column search objects are in an array, so it needs to be converted
27459		// element by element
27460		var searchCols = init.aoSearchCols;
27461
27462		if ( searchCols ) {
27463			for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
27464				if ( searchCols[i] ) {
27465					_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
27466				}
27467			}
27468		}
27469	}
27470
27471
27472	/**
27473	 * Provide backwards compatibility for column options. Note that the new options
27474	 * are mapped onto the old parameters, so this is an external interface change
27475	 * only.
27476	 *  @param {object} init Object to map
27477	 */
27478	function _fnCompatCols ( init )
27479	{
27480		_fnCompatMap( init, 'orderable',     'bSortable' );
27481		_fnCompatMap( init, 'orderData',     'aDataSort' );
27482		_fnCompatMap( init, 'orderSequence', 'asSorting' );
27483		_fnCompatMap( init, 'orderDataType', 'sortDataType' );
27484
27485		// orderData can be given as an integer
27486		var dataSort = init.aDataSort;
27487		if ( dataSort && ! $.isArray( dataSort ) ) {
27488			init.aDataSort = [ dataSort ];
27489		}
27490	}
27491
27492
27493	/**
27494	 * Browser feature detection for capabilities, quirks
27495	 *  @param {object} settings dataTables settings object
27496	 *  @memberof DataTable#oApi
27497	 */
27498	function _fnBrowserDetect( settings )
27499	{
27500		// We don't need to do this every time DataTables is constructed, the values
27501		// calculated are specific to the browser and OS configuration which we
27502		// don't expect to change between initialisations
27503		if ( ! DataTable.__browser ) {
27504			var browser = {};
27505			DataTable.__browser = browser;
27506
27507			// Scrolling feature / quirks detection
27508			var n = $('<div/>')
27509				.css( {
27510					position: 'fixed',
27511					top: 0,
27512					left: 0,
27513					height: 1,
27514					width: 1,
27515					overflow: 'hidden'
27516				} )
27517				.append(
27518					$('<div/>')
27519						.css( {
27520							position: 'absolute',
27521							top: 1,
27522							left: 1,
27523							width: 100,
27524							overflow: 'scroll'
27525						} )
27526						.append(
27527							$('<div/>')
27528								.css( {
27529									width: '100%',
27530									height: 10
27531								} )
27532						)
27533				)
27534				.appendTo( 'body' );
27535
27536			var outer = n.children();
27537			var inner = outer.children();
27538
27539			// Numbers below, in order, are:
27540			// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
27541			//
27542			// IE6 XP:                           100 100 100  83
27543			// IE7 Vista:                        100 100 100  83
27544			// IE 8+ Windows:                     83  83 100  83
27545			// Evergreen Windows:                 83  83 100  83
27546			// Evergreen Mac with scrollbars:     85  85 100  85
27547			// Evergreen Mac without scrollbars: 100 100 100 100
27548
27549			// Get scrollbar width
27550			browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
27551
27552			// IE6/7 will oversize a width 100% element inside a scrolling element, to
27553			// include the width of the scrollbar, while other browsers ensure the inner
27554			// element is contained without forcing scrolling
27555			browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
27556
27557			// In rtl text layout, some browsers (most, but not all) will place the
27558			// scrollbar on the left, rather than the right.
27559			browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
27560
27561			// IE8- don't provide height and width for getBoundingClientRect
27562			browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
27563
27564			n.remove();
27565		}
27566
27567		$.extend( settings.oBrowser, DataTable.__browser );
27568		settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
27569	}
27570
27571
27572	/**
27573	 * Array.prototype reduce[Right] method, used for browsers which don't support
27574	 * JS 1.6. Done this way to reduce code size, since we iterate either way
27575	 *  @param {object} settings dataTables settings object
27576	 *  @memberof DataTable#oApi
27577	 */
27578	function _fnReduce ( that, fn, init, start, end, inc )
27579	{
27580		var
27581			i = start,
27582			value,
27583			isSet = false;
27584
27585		if ( init !== undefined ) {
27586			value = init;
27587			isSet = true;
27588		}
27589
27590		while ( i !== end ) {
27591			if ( ! that.hasOwnProperty(i) ) {
27592				continue;
27593			}
27594
27595			value = isSet ?
27596				fn( value, that[i], i, that ) :
27597				that[i];
27598
27599			isSet = true;
27600			i += inc;
27601		}
27602
27603		return value;
27604	}
27605
27606	/**
27607	 * Add a column to the list used for the table with default values
27608	 *  @param {object} oSettings dataTables settings object
27609	 *  @param {node} nTh The th element for this column
27610	 *  @memberof DataTable#oApi
27611	 */
27612	function _fnAddColumn( oSettings, nTh )
27613	{
27614		// Add column to aoColumns array
27615		var oDefaults = DataTable.defaults.column;
27616		var iCol = oSettings.aoColumns.length;
27617		var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
27618			"nTh": nTh ? nTh : document.createElement('th'),
27619			"sTitle":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',
27620			"aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
27621			"mData": oDefaults.mData ? oDefaults.mData : iCol,
27622			idx: iCol
27623		} );
27624		oSettings.aoColumns.push( oCol );
27625
27626		// Add search object for column specific search. Note that the `searchCols[ iCol ]`
27627		// passed into extend can be undefined. This allows the user to give a default
27628		// with only some of the parameters defined, and also not give a default
27629		var searchCols = oSettings.aoPreSearchCols;
27630		searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
27631
27632		// Use the default column options function to initialise classes etc
27633		_fnColumnOptions( oSettings, iCol, $(nTh).data() );
27634	}
27635
27636
27637	/**
27638	 * Apply options for a column
27639	 *  @param {object} oSettings dataTables settings object
27640	 *  @param {int} iCol column index to consider
27641	 *  @param {object} oOptions object with sType, bVisible and bSearchable etc
27642	 *  @memberof DataTable#oApi
27643	 */
27644	function _fnColumnOptions( oSettings, iCol, oOptions )
27645	{
27646		var oCol = oSettings.aoColumns[ iCol ];
27647		var oClasses = oSettings.oClasses;
27648		var th = $(oCol.nTh);
27649
27650		// Try to get width information from the DOM. We can't get it from CSS
27651		// as we'd need to parse the CSS stylesheet. `width` option can override
27652		if ( ! oCol.sWidthOrig ) {
27653			// Width attribute
27654			oCol.sWidthOrig = th.attr('width') || null;
27655
27656			// Style attribute
27657			var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
27658			if ( t ) {
27659				oCol.sWidthOrig = t[1];
27660			}
27661		}
27662
27663		/* User specified column options */
27664		if ( oOptions !== undefined && oOptions !== null )
27665		{
27666			// Backwards compatibility
27667			_fnCompatCols( oOptions );
27668
27669			// Map camel case parameters to their Hungarian counterparts
27670			_fnCamelToHungarian( DataTable.defaults.column, oOptions );
27671
27672			/* Backwards compatibility for mDataProp */
27673			if ( oOptions.mDataProp !== undefined && !oOptions.mData )
27674			{
27675				oOptions.mData = oOptions.mDataProp;
27676			}
27677
27678			if ( oOptions.sType )
27679			{
27680				oCol._sManualType = oOptions.sType;
27681			}
27682
27683			// `class` is a reserved word in Javascript, so we need to provide
27684			// the ability to use a valid name for the camel case input
27685			if ( oOptions.className && ! oOptions.sClass )
27686			{
27687				oOptions.sClass = oOptions.className;
27688			}
27689
27690			$.extend( oCol, oOptions );
27691			_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
27692
27693			/* iDataSort to be applied (backwards compatibility), but aDataSort will take
27694			 * priority if defined
27695			 */
27696			if ( oOptions.iDataSort !== undefined )
27697			{
27698				oCol.aDataSort = [ oOptions.iDataSort ];
27699			}
27700			_fnMap( oCol, oOptions, "aDataSort" );
27701		}
27702
27703		/* Cache the data get and set functions for speed */
27704		var mDataSrc = oCol.mData;
27705		var mData = _fnGetObjectDataFn( mDataSrc );
27706		var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
27707
27708		var attrTest = function( src ) {
27709			return typeof src === 'string' && src.indexOf('@') !== -1;
27710		};
27711		oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
27712			attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
27713		);
27714		oCol._setter = null;
27715
27716		oCol.fnGetData = function (rowData, type, meta) {
27717			var innerData = mData( rowData, type, undefined, meta );
27718
27719			return mRender && type ?
27720				mRender( innerData, type, rowData, meta ) :
27721				innerData;
27722		};
27723		oCol.fnSetData = function ( rowData, val, meta ) {
27724			return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
27725		};
27726
27727		// Indicate if DataTables should read DOM data as an object or array
27728		// Used in _fnGetRowElements
27729		if ( typeof mDataSrc !== 'number' ) {
27730			oSettings._rowReadObject = true;
27731		}
27732
27733		/* Feature sorting overrides column specific when off */
27734		if ( !oSettings.oFeatures.bSort )
27735		{
27736			oCol.bSortable = false;
27737			th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
27738		}
27739
27740		/* Check that the class assignment is correct for sorting */
27741		var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
27742		var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
27743		if ( !oCol.bSortable || (!bAsc && !bDesc) )
27744		{
27745			oCol.sSortingClass = oClasses.sSortableNone;
27746			oCol.sSortingClassJUI = "";
27747		}
27748		else if ( bAsc && !bDesc )
27749		{
27750			oCol.sSortingClass = oClasses.sSortableAsc;
27751			oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
27752		}
27753		else if ( !bAsc && bDesc )
27754		{
27755			oCol.sSortingClass = oClasses.sSortableDesc;
27756			oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
27757		}
27758		else
27759		{
27760			oCol.sSortingClass = oClasses.sSortable;
27761			oCol.sSortingClassJUI = oClasses.sSortJUI;
27762		}
27763	}
27764
27765
27766	/**
27767	 * Adjust the table column widths for new data. Note: you would probably want to
27768	 * do a redraw after calling this function!
27769	 *  @param {object} settings dataTables settings object
27770	 *  @memberof DataTable#oApi
27771	 */
27772	function _fnAdjustColumnSizing ( settings )
27773	{
27774		/* Not interested in doing column width calculation if auto-width is disabled */
27775		if ( settings.oFeatures.bAutoWidth !== false )
27776		{
27777			var columns = settings.aoColumns;
27778
27779			_fnCalculateColumnWidths( settings );
27780			for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
27781			{
27782				columns[i].nTh.style.width = columns[i].sWidth;
27783			}
27784		}
27785
27786		var scroll = settings.oScroll;
27787		if ( scroll.sY !== '' || scroll.sX !== '')
27788		{
27789			_fnScrollDraw( settings );
27790		}
27791
27792		_fnCallbackFire( settings, null, 'column-sizing', [settings] );
27793	}
27794
27795
27796	/**
27797	 * Covert the index of a visible column to the index in the data array (take account
27798	 * of hidden columns)
27799	 *  @param {object} oSettings dataTables settings object
27800	 *  @param {int} iMatch Visible column index to lookup
27801	 *  @returns {int} i the data index
27802	 *  @memberof DataTable#oApi
27803	 */
27804	function _fnVisibleToColumnIndex( oSettings, iMatch )
27805	{
27806		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
27807
27808		return typeof aiVis[iMatch] === 'number' ?
27809			aiVis[iMatch] :
27810			null;
27811	}
27812
27813
27814	/**
27815	 * Covert the index of an index in the data array and convert it to the visible
27816	 *   column index (take account of hidden columns)
27817	 *  @param {int} iMatch Column index to lookup
27818	 *  @param {object} oSettings dataTables settings object
27819	 *  @returns {int} i the data index
27820	 *  @memberof DataTable#oApi
27821	 */
27822	function _fnColumnIndexToVisible( oSettings, iMatch )
27823	{
27824		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
27825		var iPos = $.inArray( iMatch, aiVis );
27826
27827		return iPos !== -1 ? iPos : null;
27828	}
27829
27830
27831	/**
27832	 * Get the number of visible columns
27833	 *  @param {object} oSettings dataTables settings object
27834	 *  @returns {int} i the number of visible columns
27835	 *  @memberof DataTable#oApi
27836	 */
27837	function _fnVisbleColumns( oSettings )
27838	{
27839		var vis = 0;
27840
27841		// No reduce in IE8, use a loop for now
27842		$.each( oSettings.aoColumns, function ( i, col ) {
27843			if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
27844				vis++;
27845			}
27846		} );
27847
27848		return vis;
27849	}
27850
27851
27852	/**
27853	 * Get an array of column indexes that match a given property
27854	 *  @param {object} oSettings dataTables settings object
27855	 *  @param {string} sParam Parameter in aoColumns to look for - typically
27856	 *    bVisible or bSearchable
27857	 *  @returns {array} Array of indexes with matched properties
27858	 *  @memberof DataTable#oApi
27859	 */
27860	function _fnGetColumns( oSettings, sParam )
27861	{
27862		var a = [];
27863
27864		$.map( oSettings.aoColumns, function(val, i) {
27865			if ( val[sParam] ) {
27866				a.push( i );
27867			}
27868		} );
27869
27870		return a;
27871	}
27872
27873
27874	/**
27875	 * Calculate the 'type' of a column
27876	 *  @param {object} settings dataTables settings object
27877	 *  @memberof DataTable#oApi
27878	 */
27879	function _fnColumnTypes ( settings )
27880	{
27881		var columns = settings.aoColumns;
27882		var data = settings.aoData;
27883		var types = DataTable.ext.type.detect;
27884		var i, ien, j, jen, k, ken;
27885		var col, cell, detectedType, cache;
27886
27887		// For each column, spin over the
27888		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
27889			col = columns[i];
27890			cache = [];
27891
27892			if ( ! col.sType && col._sManualType ) {
27893				col.sType = col._sManualType;
27894			}
27895			else if ( ! col.sType ) {
27896				for ( j=0, jen=types.length ; j<jen ; j++ ) {
27897					for ( k=0, ken=data.length ; k<ken ; k++ ) {
27898						// Use a cache array so we only need to get the type data
27899						// from the formatter once (when using multiple detectors)
27900						if ( cache[k] === undefined ) {
27901							cache[k] = _fnGetCellData( settings, k, i, 'type' );
27902						}
27903
27904						detectedType = types[j]( cache[k], settings );
27905
27906						// If null, then this type can't apply to this column, so
27907						// rather than testing all cells, break out. There is an
27908						// exception for the last type which is `html`. We need to
27909						// scan all rows since it is possible to mix string and HTML
27910						// types
27911						if ( ! detectedType && j !== types.length-1 ) {
27912							break;
27913						}
27914
27915						// Only a single match is needed for html type since it is
27916						// bottom of the pile and very similar to string
27917						if ( detectedType === 'html' ) {
27918							break;
27919						}
27920					}
27921
27922					// Type is valid for all data points in the column - use this
27923					// type
27924					if ( detectedType ) {
27925						col.sType = detectedType;
27926						break;
27927					}
27928				}
27929
27930				// Fall back - if no type was detected, always use string
27931				if ( ! col.sType ) {
27932					col.sType = 'string';
27933				}
27934			}
27935		}
27936	}
27937
27938
27939	/**
27940	 * Take the column definitions and static columns arrays and calculate how
27941	 * they relate to column indexes. The callback function will then apply the
27942	 * definition found for a column to a suitable configuration object.
27943	 *  @param {object} oSettings dataTables settings object
27944	 *  @param {array} aoColDefs The aoColumnDefs array that is to be applied
27945	 *  @param {array} aoCols The aoColumns array that defines columns individually
27946	 *  @param {function} fn Callback function - takes two parameters, the calculated
27947	 *    column index and the definition for that column.
27948	 *  @memberof DataTable#oApi
27949	 */
27950	function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
27951	{
27952		var i, iLen, j, jLen, k, kLen, def;
27953		var columns = oSettings.aoColumns;
27954
27955		// Column definitions with aTargets
27956		if ( aoColDefs )
27957		{
27958			/* Loop over the definitions array - loop in reverse so first instance has priority */
27959			for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
27960			{
27961				def = aoColDefs[i];
27962
27963				/* Each definition can target multiple columns, as it is an array */
27964				var aTargets = def.targets !== undefined ?
27965					def.targets :
27966					def.aTargets;
27967
27968				if ( ! $.isArray( aTargets ) )
27969				{
27970					aTargets = [ aTargets ];
27971				}
27972
27973				for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
27974				{
27975					if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
27976					{
27977						/* Add columns that we don't yet know about */
27978						while( columns.length <= aTargets[j] )
27979						{
27980							_fnAddColumn( oSettings );
27981						}
27982
27983						/* Integer, basic index */
27984						fn( aTargets[j], def );
27985					}
27986					else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
27987					{
27988						/* Negative integer, right to left column counting */
27989						fn( columns.length+aTargets[j], def );
27990					}
27991					else if ( typeof aTargets[j] === 'string' )
27992					{
27993						/* Class name matching on TH element */
27994						for ( k=0, kLen=columns.length ; k<kLen ; k++ )
27995						{
27996							if ( aTargets[j] == "_all" ||
27997								$(columns[k].nTh).hasClass( aTargets[j] ) )
27998							{
27999								fn( k, def );
28000							}
28001						}
28002					}
28003				}
28004			}
28005		}
28006
28007		// Statically defined columns array
28008		if ( aoCols )
28009		{
28010			for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
28011			{
28012				fn( i, aoCols[i] );
28013			}
28014		}
28015	}
28016
28017	/**
28018	 * Add a data array to the table, creating DOM node etc. This is the parallel to
28019	 * _fnGatherData, but for adding rows from a Javascript source, rather than a
28020	 * DOM source.
28021	 *  @param {object} oSettings dataTables settings object
28022	 *  @param {array} aData data array to be added
28023	 *  @param {node} [nTr] TR element to add to the table - optional. If not given,
28024	 *    DataTables will create a row automatically
28025	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
28026	 *    if nTr is.
28027	 *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
28028	 *  @memberof DataTable#oApi
28029	 */
28030	function _fnAddData ( oSettings, aDataIn, nTr, anTds )
28031	{
28032		/* Create the object for storing information about this new row */
28033		var iRow = oSettings.aoData.length;
28034		var oData = $.extend( true, {}, DataTable.models.oRow, {
28035			src: nTr ? 'dom' : 'data',
28036			idx: iRow
28037		} );
28038
28039		oData._aData = aDataIn;
28040		oSettings.aoData.push( oData );
28041
28042		/* Create the cells */
28043		var nTd, sThisType;
28044		var columns = oSettings.aoColumns;
28045
28046		// Invalidate the column types as the new data needs to be revalidated
28047		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
28048		{
28049			columns[i].sType = null;
28050		}
28051
28052		/* Add to the display array */
28053		oSettings.aiDisplayMaster.push( iRow );
28054
28055		var id = oSettings.rowIdFn( aDataIn );
28056		if ( id !== undefined ) {
28057			oSettings.aIds[ id ] = oData;
28058		}
28059
28060		/* Create the DOM information, or register it if already present */
28061		if ( nTr || ! oSettings.oFeatures.bDeferRender )
28062		{
28063			_fnCreateTr( oSettings, iRow, nTr, anTds );
28064		}
28065
28066		return iRow;
28067	}
28068
28069
28070	/**
28071	 * Add one or more TR elements to the table. Generally we'd expect to
28072	 * use this for reading data from a DOM sourced table, but it could be
28073	 * used for an TR element. Note that if a TR is given, it is used (i.e.
28074	 * it is not cloned).
28075	 *  @param {object} settings dataTables settings object
28076	 *  @param {array|node|jQuery} trs The TR element(s) to add to the table
28077	 *  @returns {array} Array of indexes for the added rows
28078	 *  @memberof DataTable#oApi
28079	 */
28080	function _fnAddTr( settings, trs )
28081	{
28082		var row;
28083
28084		// Allow an individual node to be passed in
28085		if ( ! (trs instanceof $) ) {
28086			trs = $(trs);
28087		}
28088
28089		return trs.map( function (i, el) {
28090			row = _fnGetRowElements( settings, el );
28091			return _fnAddData( settings, row.data, el, row.cells );
28092		} );
28093	}
28094
28095
28096	/**
28097	 * Take a TR element and convert it to an index in aoData
28098	 *  @param {object} oSettings dataTables settings object
28099	 *  @param {node} n the TR element to find
28100	 *  @returns {int} index if the node is found, null if not
28101	 *  @memberof DataTable#oApi
28102	 */
28103	function _fnNodeToDataIndex( oSettings, n )
28104	{
28105		return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
28106	}
28107
28108
28109	/**
28110	 * Take a TD element and convert it into a column data index (not the visible index)
28111	 *  @param {object} oSettings dataTables settings object
28112	 *  @param {int} iRow The row number the TD/TH can be found in
28113	 *  @param {node} n The TD/TH element to find
28114	 *  @returns {int} index if the node is found, -1 if not
28115	 *  @memberof DataTable#oApi
28116	 */
28117	function _fnNodeToColumnIndex( oSettings, iRow, n )
28118	{
28119		return $.inArray( n, oSettings.aoData[ iRow ].anCells );
28120	}
28121
28122
28123	/**
28124	 * Get the data for a given cell from the internal cache, taking into account data mapping
28125	 *  @param {object} settings dataTables settings object
28126	 *  @param {int} rowIdx aoData row id
28127	 *  @param {int} colIdx Column index
28128	 *  @param {string} type data get type ('display', 'type' 'filter' 'sort')
28129	 *  @returns {*} Cell data
28130	 *  @memberof DataTable#oApi
28131	 */
28132	function _fnGetCellData( settings, rowIdx, colIdx, type )
28133	{
28134		var draw           = settings.iDraw;
28135		var col            = settings.aoColumns[colIdx];
28136		var rowData        = settings.aoData[rowIdx]._aData;
28137		var defaultContent = col.sDefaultContent;
28138		var cellData       = col.fnGetData( rowData, type, {
28139			settings: settings,
28140			row:      rowIdx,
28141			col:      colIdx
28142		} );
28143
28144		if ( cellData === undefined ) {
28145			if ( settings.iDrawError != draw && defaultContent === null ) {
28146				_fnLog( settings, 0, "Requested unknown parameter "+
28147					(typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
28148					" for row "+rowIdx+", column "+colIdx, 4 );
28149				settings.iDrawError = draw;
28150			}
28151			return defaultContent;
28152		}
28153
28154		// When the data source is null and a specific data type is requested (i.e.
28155		// not the original data), we can use default column data
28156		if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
28157			cellData = defaultContent;
28158		}
28159		else if ( typeof cellData === 'function' ) {
28160			// If the data source is a function, then we run it and use the return,
28161			// executing in the scope of the data object (for instances)
28162			return cellData.call( rowData );
28163		}
28164
28165		if ( cellData === null && type == 'display' ) {
28166			return '';
28167		}
28168		return cellData;
28169	}
28170
28171
28172	/**
28173	 * Set the value for a specific cell, into the internal data cache
28174	 *  @param {object} settings dataTables settings object
28175	 *  @param {int} rowIdx aoData row id
28176	 *  @param {int} colIdx Column index
28177	 *  @param {*} val Value to set
28178	 *  @memberof DataTable#oApi
28179	 */
28180	function _fnSetCellData( settings, rowIdx, colIdx, val )
28181	{
28182		var col     = settings.aoColumns[colIdx];
28183		var rowData = settings.aoData[rowIdx]._aData;
28184
28185		col.fnSetData( rowData, val, {
28186			settings: settings,
28187			row:      rowIdx,
28188			col:      colIdx
28189		}  );
28190	}
28191
28192
28193	// Private variable that is used to match action syntax in the data property object
28194	var __reArray = /\[.*?\]$/;
28195	var __reFn = /\(\)$/;
28196
28197	/**
28198	 * Split string on periods, taking into account escaped periods
28199	 * @param  {string} str String to split
28200	 * @return {array} Split string
28201	 */
28202	function _fnSplitObjNotation( str )
28203	{
28204		return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
28205			return s.replace(/\\./g, '.');
28206		} );
28207	}
28208
28209
28210	/**
28211	 * Return a function that can be used to get data from a source object, taking
28212	 * into account the ability to use nested objects as a source
28213	 *  @param {string|int|function} mSource The data source for the object
28214	 *  @returns {function} Data get function
28215	 *  @memberof DataTable#oApi
28216	 */
28217	function _fnGetObjectDataFn( mSource )
28218	{
28219		if ( $.isPlainObject( mSource ) )
28220		{
28221			/* Build an object of get functions, and wrap them in a single call */
28222			var o = {};
28223			$.each( mSource, function (key, val) {
28224				if ( val ) {
28225					o[key] = _fnGetObjectDataFn( val );
28226				}
28227			} );
28228
28229			return function (data, type, row, meta) {
28230				var t = o[type] || o._;
28231				return t !== undefined ?
28232					t(data, type, row, meta) :
28233					data;
28234			};
28235		}
28236		else if ( mSource === null )
28237		{
28238			/* Give an empty string for rendering / sorting etc */
28239			return function (data) { // type, row and meta also passed, but not used
28240				return data;
28241			};
28242		}
28243		else if ( typeof mSource === 'function' )
28244		{
28245			return function (data, type, row, meta) {
28246				return mSource( data, type, row, meta );
28247			};
28248		}
28249		else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
28250			mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
28251		{
28252			/* If there is a . in the source string then the data source is in a
28253			 * nested object so we loop over the data for each level to get the next
28254			 * level down. On each loop we test for undefined, and if found immediately
28255			 * return. This allows entire objects to be missing and sDefaultContent to
28256			 * be used if defined, rather than throwing an error
28257			 */
28258			var fetchData = function (data, type, src) {
28259				var arrayNotation, funcNotation, out, innerSrc;
28260
28261				if ( src !== "" )
28262				{
28263					var a = _fnSplitObjNotation( src );
28264
28265					for ( var i=0, iLen=a.length ; i<iLen ; i++ )
28266					{
28267						// Check if we are dealing with special notation
28268						arrayNotation = a[i].match(__reArray);
28269						funcNotation = a[i].match(__reFn);
28270
28271						if ( arrayNotation )
28272						{
28273							// Array notation
28274							a[i] = a[i].replace(__reArray, '');
28275
28276							// Condition allows simply [] to be passed in
28277							if ( a[i] !== "" ) {
28278								data = data[ a[i] ];
28279							}
28280							out = [];
28281
28282							// Get the remainder of the nested object to get
28283							a.splice( 0, i+1 );
28284							innerSrc = a.join('.');
28285
28286							// Traverse each entry in the array getting the properties requested
28287							if ( $.isArray( data ) ) {
28288								for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
28289									out.push( fetchData( data[j], type, innerSrc ) );
28290								}
28291							}
28292
28293							// If a string is given in between the array notation indicators, that
28294							// is used to join the strings together, otherwise an array is returned
28295							var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
28296							data = (join==="") ? out : out.join(join);
28297
28298							// The inner call to fetchData has already traversed through the remainder
28299							// of the source requested, so we exit from the loop
28300							break;
28301						}
28302						else if ( funcNotation )
28303						{
28304							// Function call
28305							a[i] = a[i].replace(__reFn, '');
28306							data = data[ a[i] ]();
28307							continue;
28308						}
28309
28310						if ( data === null || data[ a[i] ] === undefined )
28311						{
28312							return undefined;
28313						}
28314						data = data[ a[i] ];
28315					}
28316				}
28317
28318				return data;
28319			};
28320
28321			return function (data, type) { // row and meta also passed, but not used
28322				return fetchData( data, type, mSource );
28323			};
28324		}
28325		else
28326		{
28327			/* Array or flat object mapping */
28328			return function (data, type) { // row and meta also passed, but not used
28329				return data[mSource];
28330			};
28331		}
28332	}
28333
28334
28335	/**
28336	 * Return a function that can be used to set data from a source object, taking
28337	 * into account the ability to use nested objects as a source
28338	 *  @param {string|int|function} mSource The data source for the object
28339	 *  @returns {function} Data set function
28340	 *  @memberof DataTable#oApi
28341	 */
28342	function _fnSetObjectDataFn( mSource )
28343	{
28344		if ( $.isPlainObject( mSource ) )
28345		{
28346			/* Unlike get, only the underscore (global) option is used for for
28347			 * setting data since we don't know the type here. This is why an object
28348			 * option is not documented for `mData` (which is read/write), but it is
28349			 * for `mRender` which is read only.
28350			 */
28351			return _fnSetObjectDataFn( mSource._ );
28352		}
28353		else if ( mSource === null )
28354		{
28355			/* Nothing to do when the data source is null */
28356			return function () {};
28357		}
28358		else if ( typeof mSource === 'function' )
28359		{
28360			return function (data, val, meta) {
28361				mSource( data, 'set', val, meta );
28362			};
28363		}
28364		else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
28365			mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
28366		{
28367			/* Like the get, we need to get data from a nested object */
28368			var setData = function (data, val, src) {
28369				var a = _fnSplitObjNotation( src ), b;
28370				var aLast = a[a.length-1];
28371				var arrayNotation, funcNotation, o, innerSrc;
28372
28373				for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
28374				{
28375					// Check if we are dealing with an array notation request
28376					arrayNotation = a[i].match(__reArray);
28377					funcNotation = a[i].match(__reFn);
28378
28379					if ( arrayNotation )
28380					{
28381						a[i] = a[i].replace(__reArray, '');
28382						data[ a[i] ] = [];
28383
28384						// Get the remainder of the nested object to set so we can recurse
28385						b = a.slice();
28386						b.splice( 0, i+1 );
28387						innerSrc = b.join('.');
28388
28389						// Traverse each entry in the array setting the properties requested
28390						if ( $.isArray( val ) )
28391						{
28392							for ( var j=0, jLen=val.length ; j<jLen ; j++ )
28393							{
28394								o = {};
28395								setData( o, val[j], innerSrc );
28396								data[ a[i] ].push( o );
28397							}
28398						}
28399						else
28400						{
28401							// We've been asked to save data to an array, but it
28402							// isn't array data to be saved. Best that can be done
28403							// is to just save the value.
28404							data[ a[i] ] = val;
28405						}
28406
28407						// The inner call to setData has already traversed through the remainder
28408						// of the source and has set the data, thus we can exit here
28409						return;
28410					}
28411					else if ( funcNotation )
28412					{
28413						// Function call
28414						a[i] = a[i].replace(__reFn, '');
28415						data = data[ a[i] ]( val );
28416					}
28417
28418					// If the nested object doesn't currently exist - since we are
28419					// trying to set the value - create it
28420					if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
28421					{
28422						data[ a[i] ] = {};
28423					}
28424					data = data[ a[i] ];
28425				}
28426
28427				// Last item in the input - i.e, the actual set
28428				if ( aLast.match(__reFn ) )
28429				{
28430					// Function call
28431					data = data[ aLast.replace(__reFn, '') ]( val );
28432				}
28433				else
28434				{
28435					// If array notation is used, we just want to strip it and use the property name
28436					// and assign the value. If it isn't used, then we get the result we want anyway
28437					data[ aLast.replace(__reArray, '') ] = val;
28438				}
28439			};
28440
28441			return function (data, val) { // meta is also passed in, but not used
28442				return setData( data, val, mSource );
28443			};
28444		}
28445		else
28446		{
28447			/* Array or flat object mapping */
28448			return function (data, val) { // meta is also passed in, but not used
28449				data[mSource] = val;
28450			};
28451		}
28452	}
28453
28454
28455	/**
28456	 * Return an array with the full table data
28457	 *  @param {object} oSettings dataTables settings object
28458	 *  @returns array {array} aData Master data array
28459	 *  @memberof DataTable#oApi
28460	 */
28461	function _fnGetDataMaster ( settings )
28462	{
28463		return _pluck( settings.aoData, '_aData' );
28464	}
28465
28466
28467	/**
28468	 * Nuke the table
28469	 *  @param {object} oSettings dataTables settings object
28470	 *  @memberof DataTable#oApi
28471	 */
28472	function _fnClearTable( settings )
28473	{
28474		settings.aoData.length = 0;
28475		settings.aiDisplayMaster.length = 0;
28476		settings.aiDisplay.length = 0;
28477		settings.aIds = {};
28478	}
28479
28480
28481	/**
28482	 * Take an array of integers (index array) and remove a target integer (value - not
28483	 * the key!)
28484	 *  @param {array} a Index array to target
28485	 *  @param {int} iTarget value to find
28486	 *  @memberof DataTable#oApi
28487	 */
28488	function _fnDeleteIndex( a, iTarget, splice )
28489	{
28490		var iTargetIndex = -1;
28491
28492		for ( var i=0, iLen=a.length ; i<iLen ; i++ )
28493		{
28494			if ( a[i] == iTarget )
28495			{
28496				iTargetIndex = i;
28497			}
28498			else if ( a[i] > iTarget )
28499			{
28500				a[i]--;
28501			}
28502		}
28503
28504		if ( iTargetIndex != -1 && splice === undefined )
28505		{
28506			a.splice( iTargetIndex, 1 );
28507		}
28508	}
28509
28510
28511	/**
28512	 * Mark cached data as invalid such that a re-read of the data will occur when
28513	 * the cached data is next requested. Also update from the data source object.
28514	 *
28515	 * @param {object} settings DataTables settings object
28516	 * @param {int}    rowIdx   Row index to invalidate
28517	 * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'
28518	 *     or 'data'
28519	 * @param {int}    [colIdx] Column index to invalidate. If undefined the whole
28520	 *     row will be invalidated
28521	 * @memberof DataTable#oApi
28522	 *
28523	 * @todo For the modularisation of v1.11 this will need to become a callback, so
28524	 *   the sort and filter methods can subscribe to it. That will required
28525	 *   initialisation options for sorting, which is why it is not already baked in
28526	 */
28527	function _fnInvalidate( settings, rowIdx, src, colIdx )
28528	{
28529		var row = settings.aoData[ rowIdx ];
28530		var i, ien;
28531		var cellWrite = function ( cell, col ) {
28532			// This is very frustrating, but in IE if you just write directly
28533			// to innerHTML, and elements that are overwritten are GC'ed,
28534			// even if there is a reference to them elsewhere
28535			while ( cell.childNodes.length ) {
28536				cell.removeChild( cell.firstChild );
28537			}
28538
28539			cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
28540		};
28541
28542		// Are we reading last data from DOM or the data object?
28543		if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
28544			// Read the data from the DOM
28545			row._aData = _fnGetRowElements(
28546				settings, row, colIdx, colIdx === undefined ? undefined : row._aData
28547			)
28548				.data;
28549		}
28550		else {
28551			// Reading from data object, update the DOM
28552			var cells = row.anCells;
28553
28554			if ( cells ) {
28555				if ( colIdx !== undefined ) {
28556					cellWrite( cells[colIdx], colIdx );
28557				}
28558				else {
28559					for ( i=0, ien=cells.length ; i<ien ; i++ ) {
28560						cellWrite( cells[i], i );
28561					}
28562				}
28563			}
28564		}
28565
28566		// For both row and cell invalidation, the cached data for sorting and
28567		// filtering is nulled out
28568		row._aSortData = null;
28569		row._aFilterData = null;
28570
28571		// Invalidate the type for a specific column (if given) or all columns since
28572		// the data might have changed
28573		var cols = settings.aoColumns;
28574		if ( colIdx !== undefined ) {
28575			cols[ colIdx ].sType = null;
28576		}
28577		else {
28578			for ( i=0, ien=cols.length ; i<ien ; i++ ) {
28579				cols[i].sType = null;
28580			}
28581
28582			// Update DataTables special `DT_*` attributes for the row
28583			_fnRowAttributes( settings, row );
28584		}
28585	}
28586
28587
28588	/**
28589	 * Build a data source object from an HTML row, reading the contents of the
28590	 * cells that are in the row.
28591	 *
28592	 * @param {object} settings DataTables settings object
28593	 * @param {node|object} TR element from which to read data or existing row
28594	 *   object from which to re-read the data from the cells
28595	 * @param {int} [colIdx] Optional column index
28596	 * @param {array|object} [d] Data source object. If `colIdx` is given then this
28597	 *   parameter should also be given and will be used to write the data into.
28598	 *   Only the column in question will be written
28599	 * @returns {object} Object with two parameters: `data` the data read, in
28600	 *   document order, and `cells` and array of nodes (they can be useful to the
28601	 *   caller, so rather than needing a second traversal to get them, just return
28602	 *   them from here).
28603	 * @memberof DataTable#oApi
28604	 */
28605	function _fnGetRowElements( settings, row, colIdx, d )
28606	{
28607		var
28608			tds = [],
28609			td = row.firstChild,
28610			name, col, o, i=0, contents,
28611			columns = settings.aoColumns,
28612			objectRead = settings._rowReadObject;
28613
28614		// Allow the data object to be passed in, or construct
28615		d = d !== undefined ?
28616			d :
28617			objectRead ?
28618				{} :
28619				[];
28620
28621		var attr = function ( str, td  ) {
28622			if ( typeof str === 'string' ) {
28623				var idx = str.indexOf('@');
28624
28625				if ( idx !== -1 ) {
28626					var attr = str.substring( idx+1 );
28627					var setter = _fnSetObjectDataFn( str );
28628					setter( d, td.getAttribute( attr ) );
28629				}
28630			}
28631		};
28632
28633		// Read data from a cell and store into the data object
28634		var cellProcess = function ( cell ) {
28635			if ( colIdx === undefined || colIdx === i ) {
28636				col = columns[i];
28637				contents = $.trim(cell.innerHTML);
28638
28639				if ( col && col._bAttrSrc ) {
28640					var setter = _fnSetObjectDataFn( col.mData._ );
28641					setter( d, contents );
28642
28643					attr( col.mData.sort, cell );
28644					attr( col.mData.type, cell );
28645					attr( col.mData.filter, cell );
28646				}
28647				else {
28648					// Depending on the `data` option for the columns the data can
28649					// be read to either an object or an array.
vendor: 29,502 bytes, lines 28650-29743
28650					if ( objectRead ) {
28651						if ( ! col._setter ) {
28652							// Cache the setter function
28653							col._setter = _fnSetObjectDataFn( col.mData );
28654						}
28655						col._setter( d, contents );
28656					}
28657					else {
28658						d[i] = contents;
28659					}
28660				}
28661			}
28662
28663			i++;
28664		};
28665
28666		if ( td ) {
28667			// `tr` element was passed in
28668			while ( td ) {
28669				name = td.nodeName.toUpperCase();
28670
28671				if ( name == "TD" || name == "TH" ) {
28672					cellProcess( td );
28673					tds.push( td );
28674				}
28675
28676				td = td.nextSibling;
28677			}
28678		}
28679		else {
28680			// Existing row object passed in
28681			tds = row.anCells;
28682
28683			for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
28684				cellProcess( tds[j] );
28685			}
28686		}
28687
28688		// Read the ID from the DOM if present
28689		var rowNode = row.firstChild ? row : row.nTr;
28690
28691		if ( rowNode ) {
28692			var id = rowNode.getAttribute( 'id' );
28693
28694			if ( id ) {
28695				_fnSetObjectDataFn( settings.rowId )( d, id );
28696			}
28697		}
28698
28699		return {
28700			data: d,
28701			cells: tds
28702		};
28703	}
28704	/**
28705	 * Create a new TR element (and it's TD children) for a row
28706	 *  @param {object} oSettings dataTables settings object
28707	 *  @param {int} iRow Row to consider
28708	 *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,
28709	 *    DataTables will create a row automatically
28710	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
28711	 *    if nTr is.
28712	 *  @memberof DataTable#oApi
28713	 */
28714	function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
28715	{
28716		var
28717			row = oSettings.aoData[iRow],
28718			rowData = row._aData,
28719			cells = [],
28720			nTr, nTd, oCol,
28721			i, iLen;
28722
28723		if ( row.nTr === null )
28724		{
28725			nTr = nTrIn || document.createElement('tr');
28726
28727			row.nTr = nTr;
28728			row.anCells = cells;
28729
28730			/* Use a private property on the node to allow reserve mapping from the node
28731			 * to the aoData array for fast look up
28732			 */
28733			nTr._DT_RowIndex = iRow;
28734
28735			/* Special parameters can be given by the data source to be used on the row */
28736			_fnRowAttributes( oSettings, row );
28737
28738			/* Process each column */
28739			for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
28740			{
28741				oCol = oSettings.aoColumns[i];
28742
28743				nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
28744				nTd._DT_CellIndex = {
28745					row: iRow,
28746					column: i
28747				};
28748
28749				cells.push( nTd );
28750
28751				// Need to create the HTML if new, or if a rendering function is defined
28752				if ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&
28753					(!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
28754				) {
28755					nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
28756				}
28757
28758				/* Add user defined class */
28759				if ( oCol.sClass )
28760				{
28761					nTd.className += ' '+oCol.sClass;
28762				}
28763
28764				// Visibility - add or remove as required
28765				if ( oCol.bVisible && ! nTrIn )
28766				{
28767					nTr.appendChild( nTd );
28768				}
28769				else if ( ! oCol.bVisible && nTrIn )
28770				{
28771					nTd.parentNode.removeChild( nTd );
28772				}
28773
28774				if ( oCol.fnCreatedCell )
28775				{
28776					oCol.fnCreatedCell.call( oSettings.oInstance,
28777						nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
28778					);
28779				}
28780			}
28781
28782			_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
28783		}
28784
28785		// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
28786		// and deployed
28787		row.nTr.setAttribute( 'role', 'row' );
28788	}
28789
28790
28791	/**
28792	 * Add attributes to a row based on the special `DT_*` parameters in a data
28793	 * source object.
28794	 *  @param {object} settings DataTables settings object
28795	 *  @param {object} DataTables row object for the row to be modified
28796	 *  @memberof DataTable#oApi
28797	 */
28798	function _fnRowAttributes( settings, row )
28799	{
28800		var tr = row.nTr;
28801		var data = row._aData;
28802
28803		if ( tr ) {
28804			var id = settings.rowIdFn( data );
28805
28806			if ( id ) {
28807				tr.id = id;
28808			}
28809
28810			if ( data.DT_RowClass ) {
28811				// Remove any classes added by DT_RowClass before
28812				var a = data.DT_RowClass.split(' ');
28813				row.__rowc = row.__rowc ?
28814					_unique( row.__rowc.concat( a ) ) :
28815					a;
28816
28817				$(tr)
28818					.removeClass( row.__rowc.join(' ') )
28819					.addClass( data.DT_RowClass );
28820			}
28821
28822			if ( data.DT_RowAttr ) {
28823				$(tr).attr( data.DT_RowAttr );
28824			}
28825
28826			if ( data.DT_RowData ) {
28827				$(tr).data( data.DT_RowData );
28828			}
28829		}
28830	}
28831
28832
28833	/**
28834	 * Create the HTML header for the table
28835	 *  @param {object} oSettings dataTables settings object
28836	 *  @memberof DataTable#oApi
28837	 */
28838	function _fnBuildHead( oSettings )
28839	{
28840		var i, ien, cell, row, column;
28841		var thead = oSettings.nTHead;
28842		var tfoot = oSettings.nTFoot;
28843		var createHeader = $('th, td', thead).length === 0;
28844		var classes = oSettings.oClasses;
28845		var columns = oSettings.aoColumns;
28846
28847		if ( createHeader ) {
28848			row = $('<tr/>').appendTo( thead );
28849		}
28850
28851		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
28852			column = columns[i];
28853			cell = $( column.nTh ).addClass( column.sClass );
28854
28855			if ( createHeader ) {
28856				cell.appendTo( row );
28857			}
28858
28859			// 1.11 move into sorting
28860			if ( oSettings.oFeatures.bSort ) {
28861				cell.addClass( column.sSortingClass );
28862
28863				if ( column.bSortable !== false ) {
28864					cell
28865						.attr( 'tabindex', oSettings.iTabIndex )
28866						.attr( 'aria-controls', oSettings.sTableId );
28867
28868					_fnSortAttachListener( oSettings, column.nTh, i );
28869				}
28870			}
28871
28872			if ( column.sTitle != cell[0].innerHTML ) {
28873				cell.html( column.sTitle );
28874			}
28875
28876			_fnRenderer( oSettings, 'header' )(
28877				oSettings, cell, column, classes
28878			);
28879		}
28880
28881		if ( createHeader ) {
28882			_fnDetectHeader( oSettings.aoHeader, thead );
28883		}
28884
28885		/* ARIA role for the rows */
28886		$(thead).find('>tr').attr('role', 'row');
28887
28888		/* Deal with the footer - add classes if required */
28889		$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
28890		$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
28891
28892		// Cache the footer cells. Note that we only take the cells from the first
28893		// row in the footer. If there is more than one row the user wants to
28894		// interact with, they need to use the table().foot() method. Note also this
28895		// allows cells to be used for multiple columns using colspan
28896		if ( tfoot !== null ) {
28897			var cells = oSettings.aoFooter[0];
28898
28899			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
28900				column = columns[i];
28901				column.nTf = cells[i].cell;
28902
28903				if ( column.sClass ) {
28904					$(column.nTf).addClass( column.sClass );
28905				}
28906			}
28907		}
28908	}
28909
28910
28911	/**
28912	 * Draw the header (or footer) element based on the column visibility states. The
28913	 * methodology here is to use the layout array from _fnDetectHeader, modified for
28914	 * the instantaneous column visibility, to construct the new layout. The grid is
28915	 * traversed over cell at a time in a rows x columns grid fashion, although each
28916	 * cell insert can cover multiple elements in the grid - which is tracks using the
28917	 * aApplied array. Cell inserts in the grid will only occur where there isn't
28918	 * already a cell in that position.
28919	 *  @param {object} oSettings dataTables settings object
28920	 *  @param array {objects} aoSource Layout array from _fnDetectHeader
28921	 *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
28922	 *  @memberof DataTable#oApi
28923	 */
28924	function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
28925	{
28926		var i, iLen, j, jLen, k, kLen, n, nLocalTr;
28927		var aoLocal = [];
28928		var aApplied = [];
28929		var iColumns = oSettings.aoColumns.length;
28930		var iRowspan, iColspan;
28931
28932		if ( ! aoSource )
28933		{
28934			return;
28935		}
28936
28937		if (  bIncludeHidden === undefined )
28938		{
28939			bIncludeHidden = false;
28940		}
28941
28942		/* Make a copy of the master layout array, but without the visible columns in it */
28943		for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
28944		{
28945			aoLocal[i] = aoSource[i].slice();
28946			aoLocal[i].nTr = aoSource[i].nTr;
28947
28948			/* Remove any columns which are currently hidden */
28949			for ( j=iColumns-1 ; j>=0 ; j-- )
28950			{
28951				if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
28952				{
28953					aoLocal[i].splice( j, 1 );
28954				}
28955			}
28956
28957			/* Prep the applied array - it needs an element for each row */
28958			aApplied.push( [] );
28959		}
28960
28961		for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
28962		{
28963			nLocalTr = aoLocal[i].nTr;
28964
28965			/* All cells are going to be replaced, so empty out the row */
28966			if ( nLocalTr )
28967			{
28968				while( (n = nLocalTr.firstChild) )
28969				{
28970					nLocalTr.removeChild( n );
28971				}
28972			}
28973
28974			for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
28975			{
28976				iRowspan = 1;
28977				iColspan = 1;
28978
28979				/* Check to see if there is already a cell (row/colspan) covering our target
28980				 * insert point. If there is, then there is nothing to do.
28981				 */
28982				if ( aApplied[i][j] === undefined )
28983				{
28984					nLocalTr.appendChild( aoLocal[i][j].cell );
28985					aApplied[i][j] = 1;
28986
28987					/* Expand the cell to cover as many rows as needed */
28988					while ( aoLocal[i+iRowspan] !== undefined &&
28989					aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
28990					{
28991						aApplied[i+iRowspan][j] = 1;
28992						iRowspan++;
28993					}
28994
28995					/* Expand the cell to cover as many columns as needed */
28996					while ( aoLocal[i][j+iColspan] !== undefined &&
28997					aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
28998					{
28999						/* Must update the applied array over the rows for the columns */
29000						for ( k=0 ; k<iRowspan ; k++ )
29001						{
29002							aApplied[i+k][j+iColspan] = 1;
29003						}
29004						iColspan++;
29005					}
29006
29007					/* Do the actual expansion in the DOM */
29008					$(aoLocal[i][j].cell)
29009						.attr('rowspan', iRowspan)
29010						.attr('colspan', iColspan);
29011				}
29012			}
29013		}
29014	}
29015
29016
29017	/**
29018	 * Insert the required TR nodes into the table for display
29019	 *  @param {object} oSettings dataTables settings object
29020	 *  @memberof DataTable#oApi
29021	 */
29022	function _fnDraw( oSettings )
29023	{
29024		/* Provide a pre-callback function which can be used to cancel the draw is false is returned */
29025		var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
29026		if ( $.inArray( false, aPreDraw ) !== -1 )
29027		{
29028			_fnProcessingDisplay( oSettings, false );
29029			return;
29030		}
29031
29032		var i, iLen, n;
29033		var anRows = [];
29034		var iRowCount = 0;
29035		var asStripeClasses = oSettings.asStripeClasses;
29036		var iStripes = asStripeClasses.length;
29037		var iOpenRows = oSettings.aoOpenRows.length;
29038		var oLang = oSettings.oLanguage;
29039		var iInitDisplayStart = oSettings.iInitDisplayStart;
29040		var bServerSide = _fnDataSource( oSettings ) == 'ssp';
29041		var aiDisplay = oSettings.aiDisplay;
29042
29043		oSettings.bDrawing = true;
29044
29045		/* Check and see if we have an initial draw position from state saving */
29046		if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
29047		{
29048			oSettings._iDisplayStart = bServerSide ?
29049				iInitDisplayStart :
29050				iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
29051					0 :
29052					iInitDisplayStart;
29053
29054			oSettings.iInitDisplayStart = -1;
29055		}
29056
29057		var iDisplayStart = oSettings._iDisplayStart;
29058		var iDisplayEnd = oSettings.fnDisplayEnd();
29059
29060		/* Server-side processing draw intercept */
29061		if ( oSettings.bDeferLoading )
29062		{
29063			oSettings.bDeferLoading = false;
29064			oSettings.iDraw++;
29065			_fnProcessingDisplay( oSettings, false );
29066		}
29067		else if ( !bServerSide )
29068		{
29069			oSettings.iDraw++;
29070		}
29071		else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
29072		{
29073			return;
29074		}
29075
29076		if ( aiDisplay.length !== 0 )
29077		{
29078			var iStart = bServerSide ? 0 : iDisplayStart;
29079			var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
29080
29081			for ( var j=iStart ; j<iEnd ; j++ )
29082			{
29083				var iDataIndex = aiDisplay[j];
29084				var aoData = oSettings.aoData[ iDataIndex ];
29085				if ( aoData.nTr === null )
29086				{
29087					_fnCreateTr( oSettings, iDataIndex );
29088				}
29089
29090				var nRow = aoData.nTr;
29091
29092				/* Remove the old striping classes and then add the new one */
29093				if ( iStripes !== 0 )
29094				{
29095					var sStripe = asStripeClasses[ iRowCount % iStripes ];
29096					if ( aoData._sRowStripe != sStripe )
29097					{
29098						$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
29099						aoData._sRowStripe = sStripe;
29100					}
29101				}
29102
29103				// Row callback functions - might want to manipulate the row
29104				// iRowCount and j are not currently documented. Are they at all
29105				// useful?
29106				_fnCallbackFire( oSettings, 'aoRowCallback', null,
29107					[nRow, aoData._aData, iRowCount, j] );
29108
29109				anRows.push( nRow );
29110				iRowCount++;
29111			}
29112		}
29113		else
29114		{
29115			/* Table is empty - create a row with an empty message in it */
29116			var sZero = oLang.sZeroRecords;
29117			if ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )
29118			{
29119				sZero = oLang.sLoadingRecords;
29120			}
29121			else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
29122			{
29123				sZero = oLang.sEmptyTable;
29124			}
29125
29126			anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
29127				.append( $('<td />', {
29128					'valign':  'top',
29129					'colSpan': _fnVisbleColumns( oSettings ),
29130					'class':   oSettings.oClasses.sRowEmpty
29131				} ).html( sZero ) )[0];
29132		}
29133
29134		/* Header and footer callbacks */
29135		_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
29136			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
29137
29138		_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
29139			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
29140
29141		var body = $(oSettings.nTBody);
29142
29143		body.children().detach();
29144		body.append( $(anRows) );
29145
29146		/* Call all required callback functions for the end of a draw */
29147		_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
29148
29149		/* Draw is complete, sorting and filtering must be as well */
29150		oSettings.bSorted = false;
29151		oSettings.bFiltered = false;
29152		oSettings.bDrawing = false;
29153	}
29154
29155
29156	/**
29157	 * Redraw the table - taking account of the various features which are enabled
29158	 *  @param {object} oSettings dataTables settings object
29159	 *  @param {boolean} [holdPosition] Keep the current paging position. By default
29160	 *    the paging is reset to the first page
29161	 *  @memberof DataTable#oApi
29162	 */
29163	function _fnReDraw( settings, holdPosition )
29164	{
29165		var
29166			features = settings.oFeatures,
29167			sort     = features.bSort,
29168			filter   = features.bFilter;
29169
29170		if ( sort ) {
29171			_fnSort( settings );
29172		}
29173
29174		if ( filter ) {
29175			_fnFilterComplete( settings, settings.oPreviousSearch );
29176		}
29177		else {
29178			// No filtering, so we want to just use the display master
29179			settings.aiDisplay = settings.aiDisplayMaster.slice();
29180		}
29181
29182		if ( holdPosition !== true ) {
29183			settings._iDisplayStart = 0;
29184		}
29185
29186		// Let any modules know about the draw hold position state (used by
29187		// scrolling internally)
29188		settings._drawHold = holdPosition;
29189
29190		_fnDraw( settings );
29191
29192		settings._drawHold = false;
29193	}
29194
29195
29196	/**
29197	 * Add the options to the page HTML for the table
29198	 *  @param {object} oSettings dataTables settings object
29199	 *  @memberof DataTable#oApi
29200	 */
29201	function _fnAddOptionsHtml ( oSettings )
29202	{
29203		var classes = oSettings.oClasses;
29204		var table = $(oSettings.nTable);
29205		var holding = $('<div/>').insertBefore( table ); // Holding element for speed
29206		var features = oSettings.oFeatures;
29207
29208		// All DataTables are wrapped in a div
29209		var insert = $('<div/>', {
29210			id:      oSettings.sTableId+'_wrapper',
29211			'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
29212		} );
29213
29214		oSettings.nHolding = holding[0];
29215		oSettings.nTableWrapper = insert[0];
29216		oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
29217
29218		/* Loop over the user set positioning and place the elements as needed */
29219		var aDom = oSettings.sDom.split('');
29220		var featureNode, cOption, nNewNode, cNext, sAttr, j;
29221		for ( var i=0 ; i<aDom.length ; i++ )
29222		{
29223			featureNode = null;
29224			cOption = aDom[i];
29225
29226			if ( cOption == '<' )
29227			{
29228				/* New container div */
29229				nNewNode = $('<div/>')[0];
29230
29231				/* Check to see if we should append an id and/or a class name to the container */
29232				cNext = aDom[i+1];
29233				if ( cNext == "'" || cNext == '"' )
29234				{
29235					sAttr = "";
29236					j = 2;
29237					while ( aDom[i+j] != cNext )
29238					{
29239						sAttr += aDom[i+j];
29240						j++;
29241					}
29242
29243					/* Replace jQuery UI constants @todo depreciated */
29244					if ( sAttr == "H" )
29245					{
29246						sAttr = classes.sJUIHeader;
29247					}
29248					else if ( sAttr == "F" )
29249					{
29250						sAttr = classes.sJUIFooter;
29251					}
29252
29253					/* The attribute can be in the format of "#id.class", "#id" or "class" This logic
29254					 * breaks the string into parts and applies them as needed
29255					 */
29256					if ( sAttr.indexOf('.') != -1 )
29257					{
29258						var aSplit = sAttr.split('.');
29259						nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
29260						nNewNode.className = aSplit[1];
29261					}
29262					else if ( sAttr.charAt(0) == "#" )
29263					{
29264						nNewNode.id = sAttr.substr(1, sAttr.length-1);
29265					}
29266					else
29267					{
29268						nNewNode.className = sAttr;
29269					}
29270
29271					i += j; /* Move along the position array */
29272				}
29273
29274				insert.append( nNewNode );
29275				insert = $(nNewNode);
29276			}
29277			else if ( cOption == '>' )
29278			{
29279				/* End container div */
29280				insert = insert.parent();
29281			}
29282			// @todo Move options into their own plugins?
29283			else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
29284			{
29285				/* Length */
29286				featureNode = _fnFeatureHtmlLength( oSettings );
29287			}
29288			else if ( cOption == 'f' && features.bFilter )
29289			{
29290				/* Filter */
29291				featureNode = _fnFeatureHtmlFilter( oSettings );
29292			}
29293			else if ( cOption == 'r' && features.bProcessing )
29294			{
29295				/* pRocessing */
29296				featureNode = _fnFeatureHtmlProcessing( oSettings );
29297			}
29298			else if ( cOption == 't' )
29299			{
29300				/* Table */
29301				featureNode = _fnFeatureHtmlTable( oSettings );
29302			}
29303			else if ( cOption ==  'i' && features.bInfo )
29304			{
29305				/* Info */
29306				featureNode = _fnFeatureHtmlInfo( oSettings );
29307			}
29308			else if ( cOption == 'p' && features.bPaginate )
29309			{
29310				/* Pagination */
29311				featureNode = _fnFeatureHtmlPaginate( oSettings );
29312			}
29313			else if ( DataTable.ext.feature.length !== 0 )
29314			{
29315				/* Plug-in features */
29316				var aoFeatures = DataTable.ext.feature;
29317				for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
29318				{
29319					if ( cOption == aoFeatures[k].cFeature )
29320					{
29321						featureNode = aoFeatures[k].fnInit( oSettings );
29322						break;
29323					}
29324				}
29325			}
29326
29327			/* Add to the 2D features array */
29328			if ( featureNode )
29329			{
29330				var aanFeatures = oSettings.aanFeatures;
29331
29332				if ( ! aanFeatures[cOption] )
29333				{
29334					aanFeatures[cOption] = [];
29335				}
29336
29337				aanFeatures[cOption].push( featureNode );
29338				insert.append( featureNode );
29339			}
29340		}
29341
29342		/* Built our DOM structure - replace the holding div with what we want */
29343		holding.replaceWith( insert );
29344		oSettings.nHolding = null;
29345	}
29346
29347
29348	/**
29349	 * Use the DOM source to create up an array of header cells. The idea here is to
29350	 * create a layout grid (array) of rows x columns, which contains a reference
29351	 * to the cell that that point in the grid (regardless of col/rowspan), such that
29352	 * any column / row could be removed and the new grid constructed
29353	 *  @param array {object} aLayout Array to store the calculated layout in
29354	 *  @param {node} nThead The header/footer element for the table
29355	 *  @memberof DataTable#oApi
29356	 */
29357	function _fnDetectHeader ( aLayout, nThead )
29358	{
29359		var nTrs = $(nThead).children('tr');
29360		var nTr, nCell;
29361		var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
29362		var bUnique;
29363		var fnShiftCol = function ( a, i, j ) {
29364			var k = a[i];
29365			while ( k[j] ) {
29366				j++;
29367			}
29368			return j;
29369		};
29370
29371		aLayout.splice( 0, aLayout.length );
29372
29373		/* We know how many rows there are in the layout - so prep it */
29374		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
29375		{
29376			aLayout.push( [] );
29377		}
29378
29379		/* Calculate a layout array */
29380		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
29381		{
29382			nTr = nTrs[i];
29383			iColumn = 0;
29384
29385			/* For every cell in the row... */
29386			nCell = nTr.firstChild;
29387			while ( nCell ) {
29388				if ( nCell.nodeName.toUpperCase() == "TD" ||
29389					nCell.nodeName.toUpperCase() == "TH" )
29390				{
29391					/* Get the col and rowspan attributes from the DOM and sanitise them */
29392					iColspan = nCell.getAttribute('colspan') * 1;
29393					iRowspan = nCell.getAttribute('rowspan') * 1;
29394					iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
29395					iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
29396
29397					/* There might be colspan cells already in this row, so shift our target
29398					 * accordingly
29399					 */
29400					iColShifted = fnShiftCol( aLayout, i, iColumn );
29401
29402					/* Cache calculation for unique columns */
29403					bUnique = iColspan === 1 ? true : false;
29404
29405					/* If there is col / rowspan, copy the information into the layout grid */
29406					for ( l=0 ; l<iColspan ; l++ )
29407					{
29408						for ( k=0 ; k<iRowspan ; k++ )
29409						{
29410							aLayout[i+k][iColShifted+l] = {
29411								"cell": nCell,
29412								"unique": bUnique
29413							};
29414							aLayout[i+k].nTr = nTr;
29415						}
29416					}
29417				}
29418				nCell = nCell.nextSibling;
29419			}
29420		}
29421	}
29422
29423
29424	/**
29425	 * Get an array of unique th elements, one for each column
29426	 *  @param {object} oSettings dataTables settings object
29427	 *  @param {node} nHeader automatically detect the layout from this node - optional
29428	 *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
29429	 *  @returns array {node} aReturn list of unique th's
29430	 *  @memberof DataTable#oApi
29431	 */
29432	function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
29433	{
29434		var aReturn = [];
29435		if ( !aLayout )
29436		{
29437			aLayout = oSettings.aoHeader;
29438			if ( nHeader )
29439			{
29440				aLayout = [];
29441				_fnDetectHeader( aLayout, nHeader );
29442			}
29443		}
29444
29445		for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
29446		{
29447			for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
29448			{
29449				if ( aLayout[i][j].unique &&
29450					(!aReturn[j] || !oSettings.bSortCellsTop) )
29451				{
29452					aReturn[j] = aLayout[i][j].cell;
29453				}
29454			}
29455		}
29456
29457		return aReturn;
29458	}
29459
29460	/**
29461	 * Create an Ajax call based on the table's settings, taking into account that
29462	 * parameters can have multiple forms, and backwards compatibility.
29463	 *
29464	 * @param {object} oSettings dataTables settings object
29465	 * @param {array} data Data to send to the server, required by
29466	 *     DataTables - may be augmented by developer callbacks
29467	 * @param {function} fn Callback function to run when data is obtained
29468	 */
29469	function _fnBuildAjax( oSettings, data, fn )
29470	{
29471		// Compatibility with 1.9-, allow fnServerData and event to manipulate
29472		_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
29473
29474		// Convert to object based for 1.10+ if using the old array scheme which can
29475		// come from server-side processing or serverParams
29476		if ( data && $.isArray(data) ) {
29477			var tmp = {};
29478			var rbracket = /(.*?)\[\]$/;
29479
29480			$.each( data, function (key, val) {
29481				var match = val.name.match(rbracket);
29482
29483				if ( match ) {
29484					// Support for arrays
29485					var name = match[0];
29486
29487					if ( ! tmp[ name ] ) {
29488						tmp[ name ] = [];
29489					}
29490					tmp[ name ].push( val.value );
29491				}
29492				else {
29493					tmp[val.name] = val.value;
29494				}
29495			} );
29496			data = tmp;
29497		}
29498
29499		var ajaxData;
29500		var ajax = oSettings.ajax;
29501		var instance = oSettings.oInstance;
29502		var callback = function ( json ) {
29503			_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
29504			fn( json );
29505		};
29506
29507		if ( $.isPlainObject( ajax ) && ajax.data )
29508		{
29509			ajaxData = ajax.data;
29510
29511			var newData = $.isFunction( ajaxData ) ?
29512				ajaxData( data, oSettings ) :  // fn can manipulate data or return
29513				ajaxData;                      // an object object or array to merge
29514
29515			// If the function returned something, use that alone
29516			data = $.isFunction( ajaxData ) && newData ?
29517				newData :
29518				$.extend( true, data, newData );
29519
29520			// Remove the data property as we've resolved it already and don't want
29521			// jQuery to do it again (it is restored at the end of the function)
29522			delete ajax.data;
29523		}
29524
29525		var baseAjax = {
29526			"data": data,
29527			"success": function (json) {
29528				var error = json.error || json.sError;
29529				if ( error ) {
29530					_fnLog( oSettings, 0, error );
29531				}
29532
29533				oSettings.json = json;
29534				callback( json );
29535			},
29536			"dataType": "json",
29537			"cache": false,
29538			"type": oSettings.sServerMethod,
29539			"error": function (xhr, error, thrown) {
29540				var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
29541
29542				if ( $.inArray( true, ret ) === -1 ) {
29543					if ( error == "parsererror" ) {
29544						_fnLog( oSettings, 0, 'Invalid JSON response', 1 );
29545					}
29546					else if ( xhr.readyState === 4 ) {
29547						_fnLog( oSettings, 0, 'Ajax error', 7 );
29548					}
29549				}
29550
29551				_fnProcessingDisplay( oSettings, false );
29552			}
29553		};
29554
29555		// Store the data submitted for the API
29556		oSettings.oAjaxData = data;
29557
29558		// Allow plug-ins and external processes to modify the data
29559		_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
29560
29561		if ( oSettings.fnServerData )
29562		{
29563			// DataTables 1.9- compatibility
29564			oSettings.fnServerData.call( instance,
29565				oSettings.sAjaxSource,
29566				$.map( data, function (val, key) { // Need to convert back to 1.9 trad format
29567					return { name: key, value: val };
29568				} ),
29569				callback,
29570				oSettings
29571			);
29572		}
29573		else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
29574		{
29575			// DataTables 1.9- compatibility
29576			oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
29577				url: ajax || oSettings.sAjaxSource
29578			} ) );
29579		}
29580		else if ( $.isFunction( ajax ) )
29581		{
29582			// Is a function - let the caller define what needs to be done
29583			oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
29584		}
29585		else
29586		{
29587			// Object to extend the base settings
29588			oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
29589
29590			// Restore for next time around
29591			ajax.data = ajaxData;
29592		}
29593	}
29594
29595
29596	/**
29597	 * Update the table using an Ajax call
29598	 *  @param {object} settings dataTables settings object
29599	 *  @returns {boolean} Block the table drawing or not
29600	 *  @memberof DataTable#oApi
29601	 */
29602	function _fnAjaxUpdate( settings )
29603	{
29604		if ( settings.bAjaxDataGet ) {
29605			settings.iDraw++;
29606			_fnProcessingDisplay( settings, true );
29607
29608			_fnBuildAjax(
29609				settings,
29610				_fnAjaxParameters( settings ),
29611				function(json) {
29612					_fnAjaxUpdateDraw( settings, json );
29613				}
29614			);
29615
29616			return false;
29617		}
29618		return true;
29619	}
29620
29621
29622	/**
29623	 * Build up the parameters in an object needed for a server-side processing
29624	 * request. Note that this is basically done twice, is different ways - a modern
29625	 * method which is used by default in DataTables 1.10 which uses objects and
29626	 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
29627	 * the sAjaxSource option is used in the initialisation, or the legacyAjax
29628	 * option is set.
29629	 *  @param {object} oSettings dataTables settings object
29630	 *  @returns {bool} block the table drawing or not
29631	 *  @memberof DataTable#oApi
29632	 */
29633	function _fnAjaxParameters( settings )
29634	{
29635		var
29636			columns = settings.aoColumns,
29637			columnCount = columns.length,
29638			features = settings.oFeatures,
29639			preSearch = settings.oPreviousSearch,
29640			preColSearch = settings.aoPreSearchCols,
29641			i, data = [], dataProp, column, columnSearch,
29642			sort = _fnSortFlatten( settings ),
29643			displayStart = settings._iDisplayStart,
29644			displayLength = features.bPaginate !== false ?
29645				settings._iDisplayLength :
29646				-1;
29647
29648		var param = function ( name, value ) {
29649			data.push( { 'name': name, 'value': value } );
29650		};
29651
29652		// DataTables 1.9- compatible method
29653		param( 'sEcho',          settings.iDraw );
29654		param( 'iColumns',       columnCount );
29655		param( 'sColumns',       _pluck( columns, 'sName' ).join(',') );
29656		param( 'iDisplayStart',  displayStart );
29657		param( 'iDisplayLength', displayLength );
29658
29659		// DataTables 1.10+ method
29660		var d = {
29661			draw:    settings.iDraw,
29662			columns: [],
29663			order:   [],
29664			start:   displayStart,
29665			length:  displayLength,
29666			search:  {
29667				value: preSearch.sSearch,
29668				regex: preSearch.bRegex
29669			}
29670		};
29671
29672		for ( i=0 ; i<columnCount ; i++ ) {
29673			column = columns[i];
29674			columnSearch = preColSearch[i];
29675			dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
29676
29677			d.columns.push( {
29678				data:       dataProp,
29679				name:       column.sName,
29680				searchable: column.bSearchable,
29681				orderable:  column.bSortable,
29682				search:     {
29683					value: columnSearch.sSearch,
29684					regex: columnSearch.bRegex
29685				}
29686			} );
29687
29688			param( "mDataProp_"+i, dataProp );
29689
29690			if ( features.bFilter ) {
29691				param( 'sSearch_'+i,     columnSearch.sSearch );
29692				param( 'bRegex_'+i,      columnSearch.bRegex );
29693				param( 'bSearchable_'+i, column.bSearchable );
29694			}
29695
29696			if ( features.bSort ) {
29697				param( 'bSortable_'+i, column.bSortable );
29698			}
29699		}
29700
29701		if ( features.bFilter ) {
29702			param( 'sSearch', preSearch.sSearch );
29703			param( 'bRegex', preSearch.bRegex );
29704		}
29705
29706		if ( features.bSort ) {
29707			$.each( sort, function ( i, val ) {
29708				d.order.push( { column: val.col, dir: val.dir } );
29709
29710				param( 'iSortCol_'+i, val.col );
29711				param( 'sSortDir_'+i, val.dir );
29712			} );
29713
29714			param( 'iSortingCols', sort.length );
29715		}
29716
29717		// If the legacy.ajax parameter is null, then we automatically decide which
29718		// form to use, based on sAjaxSource
29719		var legacy = DataTable.ext.legacy.ajax;
29720		if ( legacy === null ) {
29721			return settings.sAjaxSource ? data : d;
29722		}
29723
29724		// Otherwise, if legacy has been specified then we use that to decide on the
29725		// form
29726		return legacy ? data : d;
29727	}
29728
29729
29730	/**
29731	 * Data the data from the server (nuking the old) and redraw the table
29732	 *  @param {object} oSettings dataTables settings object
29733	 *  @param {object} json json data return from the server.
29734	 *  @param {string} json.sEcho Tracking flag for DataTables to match requests
29735	 *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
29736	 *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
29737	 *  @param {array} json.aaData The data to display on this page
29738	 *  @param {string} [json.sColumns] Column ordering (sName, comma separated)
29739	 *  @memberof DataTable#oApi
29740	 */
29741	function _fnAjaxUpdateDraw ( settings, json )
29742	{
29743		// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
29744		// Support both
29745		var compat = function ( old, modern ) {
29746			return json[old] !== undefined ? json[old] : json[modern];
29747		};
29748
29749		var data = _fnAjaxDataSrc( settings, json );
29750		var draw            = compat( 'sEcho',                'draw' );
29751		var recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );
29752		var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
29753
29754		if ( draw ) {
29755			// Protect against out of sequence returns
29756			if ( draw*1 < settings.iDraw ) {
29757				return;
29758			}
29759			settings.iDraw = draw * 1;
29760		}
29761
29762		_fnClearTable( settings );
29763		settings._iRecordsTotal   = parseInt(recordsTotal, 10);
29764		settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
29765
29766		for ( var i=0, ien=data.length ; i<ien ; i++ ) {
29767			_fnAddData( settings, data[i] );
29768		}
29769		settings.aiDisplay = settings.aiDisplayMaster.slice();
29770
29771		settings.bAjaxDataGet = false;
29772		_fnDraw( settings );
29773
29774		if ( ! settings._bInitComplete ) {
29775			_fnInitComplete( settings, json );
29776		}
29777
29778		settings.bAjaxDataGet = true;
29779		_fnProcessingDisplay( settings, false );
29780	}
29781
29782
29783	/**
29784	 * Get the data from the JSON data source to use for drawing a table. Using
29785	 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
29786	 * source object, or from a processing function.
29787	 *  @param {object} oSettings dataTables settings object
29788	 *  @param  {object} json Data source object / array from the server
29789	 *  @return {array} Array of data to use
29790	 */
29791	function _fnAjaxDataSrc ( oSettings, json )
29792	{
29793		var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
29794			oSettings.ajax.dataSrc :
29795			oSettings.sAjaxDataProp; // Compatibility with 1.9-.
29796
29797		// Compatibility with 1.9-. In order to read from aaData, check if the
29798		// default has been changed, if not, check for aaData
29799		if ( dataSrc === 'data' ) {
29800			return json.aaData || json[dataSrc];
29801		}
29802
29803		return dataSrc !== "" ?
29804			_fnGetObjectDataFn( dataSrc )( json ) :
29805			json;
29806	}
29807
29808	/**
29809	 * Generate the node required for filtering text
29810	 *  @returns {node} Filter control element
29811	 *  @param {object} oSettings dataTables settings object
29812	 *  @memberof DataTable#oApi
29813	 */
29814	function _fnFeatureHtmlFilter ( settings )
29815	{
29816		var classes = settings.oClasses;
29817		var tableId = settings.sTableId;
29818		var language = settings.oLanguage;
29819		var previousSearch = settings.oPreviousSearch;
29820		var features = settings.aanFeatures;
29821		var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
29822
29823		var str = language.sSearch;
29824		str = str.match(/_INPUT_/) ?
29825			str.replace('_INPUT_', input) :
29826			str+input;
29827
29828		var filter = $('<div/>', {
29829			'id': ! features.f ? tableId+'_filter' : null,
29830			'class': classes.sFilter
29831		} )
29832			.append( $('<label/>' ).append( str ) );
29833
29834		var searchFn = function() {
29835			/* Update all other filter input elements for the new display */
29836			var n = features.f;
29837			var val = !this.value ? "" : this.value; // mental IE8 fix :-(
29838
29839			/* Now do the filter */
29840			if ( val != previousSearch.sSearch ) {
29841				_fnFilterComplete( settings, {
29842					"sSearch": val,
29843					"bRegex": previousSearch.bRegex,
29844					"bSmart": previousSearch.bSmart ,
29845					"bCaseInsensitive": previousSearch.bCaseInsensitive
29846				} );
29847
29848				// Need to redraw, without resorting
29849				settings._iDisplayStart = 0;
29850				_fnDraw( settings );
29851			}
29852		};
29853
29854		var searchDelay = settings.searchDelay !== null ?
29855			settings.searchDelay :
29856			_fnDataSource( settings ) === 'ssp' ?
29857				400 :
29858				0;
29859
29860		var jqFilter = $('input', filter)
29861			.val( previousSearch.sSearch )
29862			.attr( 'placeholder', language.sSearchPlaceholder )
29863			.bind(
29864				'keyup.DT search.DT input.DT paste.DT cut.DT',
29865				searchDelay ?
29866					_fnThrottle( searchFn, searchDelay ) :
29867					searchFn
29868			)
29869			.bind( 'keypress.DT', function(e) {
29870				/* Prevent form submission */
29871				if ( e.keyCode == 13 ) {
29872					return false;
29873				}
29874			} )
29875			.attr('aria-controls', tableId);
29876
29877		// Update the input elements whenever the table is filtered
29878		$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
29879			if ( settings === s ) {
29880				// IE9 throws an 'unknown error' if document.activeElement is used
29881				// inside an iframe or frame...
vendor: 73,163 bytes, lines 29882-32451
29882				try {
29883					if ( jqFilter[0] !== document.activeElement ) {
29884						jqFilter.val( previousSearch.sSearch );
29885					}
29886				}
29887				catch ( e ) {}
29888			}
29889		} );
29890
29891		return filter[0];
29892	}
29893
29894
29895	/**
29896	 * Filter the table using both the global filter and column based filtering
29897	 *  @param {object} oSettings dataTables settings object
29898	 *  @param {object} oSearch search information
29899	 *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
29900	 *  @memberof DataTable#oApi
29901	 */
29902	function _fnFilterComplete ( oSettings, oInput, iForce )
29903	{
29904		var oPrevSearch = oSettings.oPreviousSearch;
29905		var aoPrevSearch = oSettings.aoPreSearchCols;
29906		var fnSaveFilter = function ( oFilter ) {
29907			/* Save the filtering values */
29908			oPrevSearch.sSearch = oFilter.sSearch;
29909			oPrevSearch.bRegex = oFilter.bRegex;
29910			oPrevSearch.bSmart = oFilter.bSmart;
29911			oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
29912		};
29913		var fnRegex = function ( o ) {
29914			// Backwards compatibility with the bEscapeRegex option
29915			return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
29916		};
29917
29918		// Resolve any column types that are unknown due to addition or invalidation
29919		// @todo As per sort - can this be moved into an event handler?
29920		_fnColumnTypes( oSettings );
29921
29922		/* In server-side processing all filtering is done by the server, so no point hanging around here */
29923		if ( _fnDataSource( oSettings ) != 'ssp' )
29924		{
29925			/* Global filter */
29926			_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
29927			fnSaveFilter( oInput );
29928
29929			/* Now do the individual column filter */
29930			for ( var i=0 ; i<aoPrevSearch.length ; i++ )
29931			{
29932				_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
29933					aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
29934			}
29935
29936			/* Custom filtering */
29937			_fnFilterCustom( oSettings );
29938		}
29939		else
29940		{
29941			fnSaveFilter( oInput );
29942		}
29943
29944		/* Tell the draw function we have been filtering */
29945		oSettings.bFiltered = true;
29946		_fnCallbackFire( oSettings, null, 'search', [oSettings] );
29947	}
29948
29949
29950	/**
29951	 * Apply custom filtering functions
29952	 *  @param {object} oSettings dataTables settings object
29953	 *  @memberof DataTable#oApi
29954	 */
29955	function _fnFilterCustom( settings )
29956	{
29957		var filters = DataTable.ext.search;
29958		var displayRows = settings.aiDisplay;
29959		var row, rowIdx;
29960
29961		for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
29962			var rows = [];
29963
29964			// Loop over each row and see if it should be included
29965			for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
29966				rowIdx = displayRows[ j ];
29967				row = settings.aoData[ rowIdx ];
29968
29969				if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
29970					rows.push( rowIdx );
29971				}
29972			}
29973
29974			// So the array reference doesn't break set the results into the
29975			// existing array
29976			displayRows.length = 0;
29977			$.merge( displayRows, rows );
29978		}
29979	}
29980
29981
29982	/**
29983	 * Filter the table on a per-column basis
29984	 *  @param {object} oSettings dataTables settings object
29985	 *  @param {string} sInput string to filter on
29986	 *  @param {int} iColumn column to filter
29987	 *  @param {bool} bRegex treat search string as a regular expression or not
29988	 *  @param {bool} bSmart use smart filtering or not
29989	 *  @param {bool} bCaseInsensitive Do case insenstive matching or not
29990	 *  @memberof DataTable#oApi
29991	 */
29992	function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
29993	{
29994		if ( searchStr === '' ) {
29995			return;
29996		}
29997
29998		var data;
29999		var display = settings.aiDisplay;
30000		var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
30001
30002		for ( var i=display.length-1 ; i>=0 ; i-- ) {
30003			data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
30004
30005			if ( ! rpSearch.test( data ) ) {
30006				display.splice( i, 1 );
30007			}
30008		}
30009	}
30010
30011
30012	/**
30013	 * Filter the data table based on user input and draw the table
30014	 *  @param {object} settings dataTables settings object
30015	 *  @param {string} input string to filter on
30016	 *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
30017	 *  @param {bool} regex treat as a regular expression or not
30018	 *  @param {bool} smart perform smart filtering or not
30019	 *  @param {bool} caseInsensitive Do case insenstive matching or not
30020	 *  @memberof DataTable#oApi
30021	 */
30022	function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
30023	{
30024		var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
30025		var prevSearch = settings.oPreviousSearch.sSearch;
30026		var displayMaster = settings.aiDisplayMaster;
30027		var display, invalidated, i;
30028
30029		// Need to take account of custom filtering functions - always filter
30030		if ( DataTable.ext.search.length !== 0 ) {
30031			force = true;
30032		}
30033
30034		// Check if any of the rows were invalidated
30035		invalidated = _fnFilterData( settings );
30036
30037		// If the input is blank - we just want the full data set
30038		if ( input.length <= 0 ) {
30039			settings.aiDisplay = displayMaster.slice();
30040		}
30041		else {
30042			// New search - start from the master array
30043			if ( invalidated ||
30044				force ||
30045				prevSearch.length > input.length ||
30046				input.indexOf(prevSearch) !== 0 ||
30047				settings.bSorted // On resort, the display master needs to be
30048								 // re-filtered since indexes will have changed
30049			) {
30050				settings.aiDisplay = displayMaster.slice();
30051			}
30052
30053			// Search the display array
30054			display = settings.aiDisplay;
30055
30056			for ( i=display.length-1 ; i>=0 ; i-- ) {
30057				if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
30058					display.splice( i, 1 );
30059				}
30060			}
30061		}
30062	}
30063
30064
30065	/**
30066	 * Build a regular expression object suitable for searching a table
30067	 *  @param {string} sSearch string to search for
30068	 *  @param {bool} bRegex treat as a regular expression or not
30069	 *  @param {bool} bSmart perform smart filtering or not
30070	 *  @param {bool} bCaseInsensitive Do case insensitive matching or not
30071	 *  @returns {RegExp} constructed object
30072	 *  @memberof DataTable#oApi
30073	 */
30074	function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
30075	{
30076		search = regex ?
30077			search :
30078			_fnEscapeRegex( search );
30079
30080		if ( smart ) {
30081			/* For smart filtering we want to allow the search to work regardless of
30082			 * word order. We also want double quoted text to be preserved, so word
30083			 * order is important - a la google. So this is what we want to
30084			 * generate:
30085			 *
30086			 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
30087			 */
30088			var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
30089				if ( word.charAt(0) === '"' ) {
30090					var m = word.match( /^"(.*)"$/ );
30091					word = m ? m[1] : word;
30092				}
30093
30094				return word.replace('"', '');
30095			} );
30096
30097			search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
30098		}
30099
30100		return new RegExp( search, caseInsensitive ? 'i' : '' );
30101	}
30102
30103
30104	/**
30105	 * Escape a string such that it can be used in a regular expression
30106	 *  @param {string} sVal string to escape
30107	 *  @returns {string} escaped string
30108	 *  @memberof DataTable#oApi
30109	 */
30110	var _fnEscapeRegex = DataTable.util.escapeRegex;
30111
30112	var __filter_div = $('<div>')[0];
30113	var __filter_div_textContent = __filter_div.textContent !== undefined;
30114
30115	// Update the filtering data for each row if needed (by invalidation or first run)
30116	function _fnFilterData ( settings )
30117	{
30118		var columns = settings.aoColumns;
30119		var column;
30120		var i, j, ien, jen, filterData, cellData, row;
30121		var fomatters = DataTable.ext.type.search;
30122		var wasInvalidated = false;
30123
30124		for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
30125			row = settings.aoData[i];
30126
30127			if ( ! row._aFilterData ) {
30128				filterData = [];
30129
30130				for ( j=0, jen=columns.length ; j<jen ; j++ ) {
30131					column = columns[j];
30132
30133					if ( column.bSearchable ) {
30134						cellData = _fnGetCellData( settings, i, j, 'filter' );
30135
30136						if ( fomatters[ column.sType ] ) {
30137							cellData = fomatters[ column.sType ]( cellData );
30138						}
30139
30140						// Search in DataTables 1.10 is string based. In 1.11 this
30141						// should be altered to also allow strict type checking.
30142						if ( cellData === null ) {
30143							cellData = '';
30144						}
30145
30146						if ( typeof cellData !== 'string' && cellData.toString ) {
30147							cellData = cellData.toString();
30148						}
30149					}
30150					else {
30151						cellData = '';
30152					}
30153
30154					// If it looks like there is an HTML entity in the string,
30155					// attempt to decode it so sorting works as expected. Note that
30156					// we could use a single line of jQuery to do this, but the DOM
30157					// method used here is much faster http://jsperf.com/html-decode
30158					if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
30159						__filter_div.innerHTML = cellData;
30160						cellData = __filter_div_textContent ?
30161							__filter_div.textContent :
30162							__filter_div.innerText;
30163					}
30164
30165					if ( cellData.replace ) {
30166						cellData = cellData.replace(/[\r\n]/g, '');
30167					}
30168
30169					filterData.push( cellData );
30170				}
30171
30172				row._aFilterData = filterData;
30173				row._sFilterRow = filterData.join('  ');
30174				wasInvalidated = true;
30175			}
30176		}
30177
30178		return wasInvalidated;
30179	}
30180
30181
30182	/**
30183	 * Convert from the internal Hungarian notation to camelCase for external
30184	 * interaction
30185	 *  @param {object} obj Object to convert
30186	 *  @returns {object} Inverted object
30187	 *  @memberof DataTable#oApi
30188	 */
30189	function _fnSearchToCamel ( obj )
30190	{
30191		return {
30192			search:          obj.sSearch,
30193			smart:           obj.bSmart,
30194			regex:           obj.bRegex,
30195			caseInsensitive: obj.bCaseInsensitive
30196		};
30197	}
30198
30199
30200
30201	/**
30202	 * Convert from camelCase notation to the internal Hungarian. We could use the
30203	 * Hungarian convert function here, but this is cleaner
30204	 *  @param {object} obj Object to convert
30205	 *  @returns {object} Inverted object
30206	 *  @memberof DataTable#oApi
30207	 */
30208	function _fnSearchToHung ( obj )
30209	{
30210		return {
30211			sSearch:          obj.search,
30212			bSmart:           obj.smart,
30213			bRegex:           obj.regex,
30214			bCaseInsensitive: obj.caseInsensitive
30215		};
30216	}
30217
30218	/**
30219	 * Generate the node required for the info display
30220	 *  @param {object} oSettings dataTables settings object
30221	 *  @returns {node} Information element
30222	 *  @memberof DataTable#oApi
30223	 */
30224	function _fnFeatureHtmlInfo ( settings )
30225	{
30226		var
30227			tid = settings.sTableId,
30228			nodes = settings.aanFeatures.i,
30229			n = $('<div/>', {
30230				'class': settings.oClasses.sInfo,
30231				'id': ! nodes ? tid+'_info' : null
30232			} );
30233
30234		if ( ! nodes ) {
30235			// Update display on each draw
30236			settings.aoDrawCallback.push( {
30237				"fn": _fnUpdateInfo,
30238				"sName": "information"
30239			} );
30240
30241			n
30242				.attr( 'role', 'status' )
30243				.attr( 'aria-live', 'polite' );
30244
30245			// Table is described by our info div
30246			$(settings.nTable).attr( 'aria-describedby', tid+'_info' );
30247		}
30248
30249		return n[0];
30250	}
30251
30252
30253	/**
30254	 * Update the information elements in the display
30255	 *  @param {object} settings dataTables settings object
30256	 *  @memberof DataTable#oApi
30257	 */
30258	function _fnUpdateInfo ( settings )
30259	{
30260		/* Show information about the table */
30261		var nodes = settings.aanFeatures.i;
30262		if ( nodes.length === 0 ) {
30263			return;
30264		}
30265
30266		var
30267			lang  = settings.oLanguage,
30268			start = settings._iDisplayStart+1,
30269			end   = settings.fnDisplayEnd(),
30270			max   = settings.fnRecordsTotal(),
30271			total = settings.fnRecordsDisplay(),
30272			out   = total ?
30273				lang.sInfo :
30274				lang.sInfoEmpty;
30275
30276		if ( total !== max ) {
30277			/* Record set after filtering */
30278			out += ' ' + lang.sInfoFiltered;
30279		}
30280
30281		// Convert the macros
30282		out += lang.sInfoPostFix;
30283		out = _fnInfoMacros( settings, out );
30284
30285		var callback = lang.fnInfoCallback;
30286		if ( callback !== null ) {
30287			out = callback.call( settings.oInstance,
30288				settings, start, end, max, total, out
30289			);
30290		}
30291
30292		$(nodes).html( out );
30293	}
30294
30295
30296	function _fnInfoMacros ( settings, str )
30297	{
30298		// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
30299		// internally
30300		var
30301			formatter  = settings.fnFormatNumber,
30302			start      = settings._iDisplayStart+1,
30303			len        = settings._iDisplayLength,
30304			vis        = settings.fnRecordsDisplay(),
30305			all        = len === -1;
30306
30307		return str.
30308		replace(/_START_/g, formatter.call( settings, start ) ).
30309		replace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).
30310		replace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).
30311		replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
30312		replace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
30313		replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
30314	}
30315
30316
30317
30318	/**
30319	 * Draw the table for the first time, adding all required features
30320	 *  @param {object} settings dataTables settings object
30321	 *  @memberof DataTable#oApi
30322	 */
30323	function _fnInitialise ( settings )
30324	{
30325		var i, iLen, iAjaxStart=settings.iInitDisplayStart;
30326		var columns = settings.aoColumns, column;
30327		var features = settings.oFeatures;
30328		var deferLoading = settings.bDeferLoading; // value modified by the draw
30329
30330		/* Ensure that the table data is fully initialised */
30331		if ( ! settings.bInitialised ) {
30332			setTimeout( function(){ _fnInitialise( settings ); }, 200 );
30333			return;
30334		}
30335
30336		/* Show the display HTML options */
30337		_fnAddOptionsHtml( settings );
30338
30339		/* Build and draw the header / footer for the table */
30340		_fnBuildHead( settings );
30341		_fnDrawHead( settings, settings.aoHeader );
30342		_fnDrawHead( settings, settings.aoFooter );
30343
30344		/* Okay to show that something is going on now */
30345		_fnProcessingDisplay( settings, true );
30346
30347		/* Calculate sizes for columns */
30348		if ( features.bAutoWidth ) {
30349			_fnCalculateColumnWidths( settings );
30350		}
30351
30352		for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
30353			column = columns[i];
30354
30355			if ( column.sWidth ) {
30356				column.nTh.style.width = _fnStringToCss( column.sWidth );
30357			}
30358		}
30359
30360		_fnCallbackFire( settings, null, 'preInit', [settings] );
30361
30362		// If there is default sorting required - let's do it. The sort function
30363		// will do the drawing for us. Otherwise we draw the table regardless of the
30364		// Ajax source - this allows the table to look initialised for Ajax sourcing
30365		// data (show 'loading' message possibly)
30366		_fnReDraw( settings );
30367
30368		// Server-side processing init complete is done by _fnAjaxUpdateDraw
30369		var dataSrc = _fnDataSource( settings );
30370		if ( dataSrc != 'ssp' || deferLoading ) {
30371			// if there is an ajax source load the data
30372			if ( dataSrc == 'ajax' ) {
30373				_fnBuildAjax( settings, [], function(json) {
30374					var aData = _fnAjaxDataSrc( settings, json );
30375
30376					// Got the data - add it to the table
30377					for ( i=0 ; i<aData.length ; i++ ) {
30378						_fnAddData( settings, aData[i] );
30379					}
30380
30381					// Reset the init display for cookie saving. We've already done
30382					// a filter, and therefore cleared it before. So we need to make
30383					// it appear 'fresh'
30384					settings.iInitDisplayStart = iAjaxStart;
30385
30386					_fnReDraw( settings );
30387
30388					_fnProcessingDisplay( settings, false );
30389					_fnInitComplete( settings, json );
30390				}, settings );
30391			}
30392			else {
30393				_fnProcessingDisplay( settings, false );
30394				_fnInitComplete( settings );
30395			}
30396		}
30397	}
30398
30399
30400	/**
30401	 * Draw the table for the first time, adding all required features
30402	 *  @param {object} oSettings dataTables settings object
30403	 *  @param {object} [json] JSON from the server that completed the table, if using Ajax source
30404	 *    with client-side processing (optional)
30405	 *  @memberof DataTable#oApi
30406	 */
30407	function _fnInitComplete ( settings, json )
30408	{
30409		settings._bInitComplete = true;
30410
30411		// When data was added after the initialisation (data or Ajax) we need to
30412		// calculate the column sizing
30413		if ( json || settings.oInit.aaData ) {
30414			_fnAdjustColumnSizing( settings );
30415		}
30416
30417		_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
30418		_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
30419	}
30420
30421
30422	function _fnLengthChange ( settings, val )
30423	{
30424		var len = parseInt( val, 10 );
30425		settings._iDisplayLength = len;
30426
30427		_fnLengthOverflow( settings );
30428
30429		// Fire length change event
30430		_fnCallbackFire( settings, null, 'length', [settings, len] );
30431	}
30432
30433
30434	/**
30435	 * Generate the node required for user display length changing
30436	 *  @param {object} settings dataTables settings object
30437	 *  @returns {node} Display length feature node
30438	 *  @memberof DataTable#oApi
30439	 */
30440	function _fnFeatureHtmlLength ( settings )
30441	{
30442		var
30443			classes  = settings.oClasses,
30444			tableId  = settings.sTableId,
30445			menu     = settings.aLengthMenu,
30446			d2       = $.isArray( menu[0] ),
30447			lengths  = d2 ? menu[0] : menu,
30448			language = d2 ? menu[1] : menu;
30449
30450		var select = $('<select/>', {
30451			'name':          tableId+'_length',
30452			'aria-controls': tableId,
30453			'class':         classes.sLengthSelect
30454		} );
30455
30456		for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
30457			select[0][ i ] = new Option( language[i], lengths[i] );
30458		}
30459
30460		var div = $('<div><label/></div>').addClass( classes.sLength );
30461		if ( ! settings.aanFeatures.l ) {
30462			div[0].id = tableId+'_length';
30463		}
30464
30465		div.children().append(
30466			settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
30467		);
30468
30469		// Can't use `select` variable as user might provide their own and the
30470		// reference is broken by the use of outerHTML
30471		$('select', div)
30472			.val( settings._iDisplayLength )
30473			.bind( 'change.DT', function(e) {
30474				_fnLengthChange( settings, $(this).val() );
30475				_fnDraw( settings );
30476			} );
30477
30478		// Update node value whenever anything changes the table's length
30479		$(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
30480			if ( settings === s ) {
30481				$('select', div).val( len );
30482			}
30483		} );
30484
30485		return div[0];
30486	}
30487
30488
30489
30490	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
30491	 * Note that most of the paging logic is done in
30492	 * DataTable.ext.pager
30493	 */
30494
30495	/**
30496	 * Generate the node required for default pagination
30497	 *  @param {object} oSettings dataTables settings object
30498	 *  @returns {node} Pagination feature node
30499	 *  @memberof DataTable#oApi
30500	 */
30501	function _fnFeatureHtmlPaginate ( settings )
30502	{
30503		var
30504			type   = settings.sPaginationType,
30505			plugin = DataTable.ext.pager[ type ],
30506			modern = typeof plugin === 'function',
30507			redraw = function( settings ) {
30508				_fnDraw( settings );
30509			},
30510			node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
30511			features = settings.aanFeatures;
30512
30513		if ( ! modern ) {
30514			plugin.fnInit( settings, node, redraw );
30515		}
30516
30517		/* Add a draw callback for the pagination on first instance, to update the paging display */
30518		if ( ! features.p )
30519		{
30520			node.id = settings.sTableId+'_paginate';
30521
30522			settings.aoDrawCallback.push( {
30523				"fn": function( settings ) {
30524					if ( modern ) {
30525						var
30526							start      = settings._iDisplayStart,
30527							len        = settings._iDisplayLength,
30528							visRecords = settings.fnRecordsDisplay(),
30529							all        = len === -1,
30530							page = all ? 0 : Math.ceil( start / len ),
30531							pages = all ? 1 : Math.ceil( visRecords / len ),
30532							buttons = plugin(page, pages),
30533							i, ien;
30534
30535						for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
30536							_fnRenderer( settings, 'pageButton' )(
30537								settings, features.p[i], i, buttons, page, pages
30538							);
30539						}
30540					}
30541					else {
30542						plugin.fnUpdate( settings, redraw );
30543					}
30544				},
30545				"sName": "pagination"
30546			} );
30547		}
30548
30549		return node;
30550	}
30551
30552
30553	/**
30554	 * Alter the display settings to change the page
30555	 *  @param {object} settings DataTables settings object
30556	 *  @param {string|int} action Paging action to take: "first", "previous",
30557	 *    "next" or "last" or page number to jump to (integer)
30558	 *  @param [bool] redraw Automatically draw the update or not
30559	 *  @returns {bool} true page has changed, false - no change
30560	 *  @memberof DataTable#oApi
30561	 */
30562	function _fnPageChange ( settings, action, redraw )
30563	{
30564		var
30565			start     = settings._iDisplayStart,
30566			len       = settings._iDisplayLength,
30567			records   = settings.fnRecordsDisplay();
30568
30569		if ( records === 0 || len === -1 )
30570		{
30571			start = 0;
30572		}
30573		else if ( typeof action === "number" )
30574		{
30575			start = action * len;
30576
30577			if ( start > records )
30578			{
30579				start = 0;
30580			}
30581		}
30582		else if ( action == "first" )
30583		{
30584			start = 0;
30585		}
30586		else if ( action == "previous" )
30587		{
30588			start = len >= 0 ?
30589				start - len :
30590				0;
30591
30592			if ( start < 0 )
30593			{
30594				start = 0;
30595			}
30596		}
30597		else if ( action == "next" )
30598		{
30599			if ( start + len < records )
30600			{
30601				start += len;
30602			}
30603		}
30604		else if ( action == "last" )
30605		{
30606			start = Math.floor( (records-1) / len) * len;
30607		}
30608		else
30609		{
30610			_fnLog( settings, 0, "Unknown paging action: "+action, 5 );
30611		}
30612
30613		var changed = settings._iDisplayStart !== start;
30614		settings._iDisplayStart = start;
30615
30616		if ( changed ) {
30617			_fnCallbackFire( settings, null, 'page', [settings] );
30618
30619			if ( redraw ) {
30620				_fnDraw( settings );
30621			}
30622		}
30623
30624		return changed;
30625	}
30626
30627
30628
30629	/**
30630	 * Generate the node required for the processing node
30631	 *  @param {object} settings dataTables settings object
30632	 *  @returns {node} Processing element
30633	 *  @memberof DataTable#oApi
30634	 */
30635	function _fnFeatureHtmlProcessing ( settings )
30636	{
30637		return $('<div/>', {
30638			'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
30639			'class': settings.oClasses.sProcessing
30640		} )
30641			.html( settings.oLanguage.sProcessing )
30642			.insertBefore( settings.nTable )[0];
30643	}
30644
30645
30646	/**
30647	 * Display or hide the processing indicator
30648	 *  @param {object} settings dataTables settings object
30649	 *  @param {bool} show Show the processing indicator (true) or not (false)
30650	 *  @memberof DataTable#oApi
30651	 */
30652	function _fnProcessingDisplay ( settings, show )
30653	{
30654		if ( settings.oFeatures.bProcessing ) {
30655			$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
30656		}
30657
30658		_fnCallbackFire( settings, null, 'processing', [settings, show] );
30659	}
30660
30661	/**
30662	 * Add any control elements for the table - specifically scrolling
30663	 *  @param {object} settings dataTables settings object
30664	 *  @returns {node} Node to add to the DOM
30665	 *  @memberof DataTable#oApi
30666	 */
30667	function _fnFeatureHtmlTable ( settings )
30668	{
30669		var table = $(settings.nTable);
30670
30671		// Add the ARIA grid role to the table
30672		table.attr( 'role', 'grid' );
30673
30674		// Scrolling from here on in
30675		var scroll = settings.oScroll;
30676
30677		if ( scroll.sX === '' && scroll.sY === '' ) {
30678			return settings.nTable;
30679		}
30680
30681		var scrollX = scroll.sX;
30682		var scrollY = scroll.sY;
30683		var classes = settings.oClasses;
30684		var caption = table.children('caption');
30685		var captionSide = caption.length ? caption[0]._captionSide : null;
30686		var headerClone = $( table[0].cloneNode(false) );
30687		var footerClone = $( table[0].cloneNode(false) );
30688		var footer = table.children('tfoot');
30689		var _div = '<div/>';
30690		var size = function ( s ) {
30691			return !s ? null : _fnStringToCss( s );
30692		};
30693
30694		if ( ! footer.length ) {
30695			footer = null;
30696		}
30697
30698		/*
30699		 * The HTML structure that we want to generate in this function is:
30700		 *  div - scroller
30701		 *    div - scroll head
30702		 *      div - scroll head inner
30703		 *        table - scroll head table
30704		 *          thead - thead
30705		 *    div - scroll body
30706		 *      table - table (master table)
30707		 *        thead - thead clone for sizing
30708		 *        tbody - tbody
30709		 *    div - scroll foot
30710		 *      div - scroll foot inner
30711		 *        table - scroll foot table
30712		 *          tfoot - tfoot
30713		 */
30714		var scroller = $( _div, { 'class': classes.sScrollWrapper } )
30715			.append(
30716				$(_div, { 'class': classes.sScrollHead } )
30717					.css( {
30718						overflow: 'hidden',
30719						position: 'relative',
30720						border: 0,
30721						width: scrollX ? size(scrollX) : '100%'
30722					} )
30723					.append(
30724						$(_div, { 'class': classes.sScrollHeadInner } )
30725							.css( {
30726								'box-sizing': 'content-box',
30727								width: scroll.sXInner || '100%'
30728							} )
30729							.append(
30730								headerClone
30731									.removeAttr('id')
30732									.css( 'margin-left', 0 )
30733									.append( captionSide === 'top' ? caption : null )
30734									.append(
30735										table.children('thead')
30736									)
30737							)
30738					)
30739			)
30740			.append(
30741				$(_div, { 'class': classes.sScrollBody } )
30742					.css( {
30743						position: 'relative',
30744						overflow: 'auto',
30745						width: size( scrollX )
30746					} )
30747					.append( table )
30748			);
30749
30750		if ( footer ) {
30751			scroller.append(
30752				$(_div, { 'class': classes.sScrollFoot } )
30753					.css( {
30754						overflow: 'hidden',
30755						border: 0,
30756						width: scrollX ? size(scrollX) : '100%'
30757					} )
30758					.append(
30759						$(_div, { 'class': classes.sScrollFootInner } )
30760							.append(
30761								footerClone
30762									.removeAttr('id')
30763									.css( 'margin-left', 0 )
30764									.append( captionSide === 'bottom' ? caption : null )
30765									.append(
30766										table.children('tfoot')
30767									)
30768							)
30769					)
30770			);
30771		}
30772
30773		var children = scroller.children();
30774		var scrollHead = children[0];
30775		var scrollBody = children[1];
30776		var scrollFoot = footer ? children[2] : null;
30777
30778		// When the body is scrolled, then we also want to scroll the headers
30779		if ( scrollX ) {
30780			$(scrollBody).on( 'scroll.DT', function (e) {
30781				var scrollLeft = this.scrollLeft;
30782
30783				scrollHead.scrollLeft = scrollLeft;
30784
30785				if ( footer ) {
30786					scrollFoot.scrollLeft = scrollLeft;
30787				}
30788			} );
30789		}
30790
30791		$(scrollBody).css(
30792			scrollY && scroll.bCollapse ? 'max-height' : 'height',
30793			scrollY
30794		);
30795
30796		settings.nScrollHead = scrollHead;
30797		settings.nScrollBody = scrollBody;
30798		settings.nScrollFoot = scrollFoot;
30799
30800		// On redraw - align columns
30801		settings.aoDrawCallback.push( {
30802			"fn": _fnScrollDraw,
30803			"sName": "scrolling"
30804		} );
30805
30806		return scroller[0];
30807	}
30808
30809
30810
30811	/**
30812	 * Update the header, footer and body tables for resizing - i.e. column
30813	 * alignment.
30814	 *
30815	 * Welcome to the most horrible function DataTables. The process that this
30816	 * function follows is basically:
30817	 *   1. Re-create the table inside the scrolling div
30818	 *   2. Take live measurements from the DOM
30819	 *   3. Apply the measurements to align the columns
30820	 *   4. Clean up
30821	 *
30822	 *  @param {object} settings dataTables settings object
30823	 *  @memberof DataTable#oApi
30824	 */
30825	function _fnScrollDraw ( settings )
30826	{
30827		// Given that this is such a monster function, a lot of variables are use
30828		// to try and keep the minimised size as small as possible
30829		var
30830			scroll         = settings.oScroll,
30831			scrollX        = scroll.sX,
30832			scrollXInner   = scroll.sXInner,
30833			scrollY        = scroll.sY,
30834			barWidth       = scroll.iBarWidth,
30835			divHeader      = $(settings.nScrollHead),
30836			divHeaderStyle = divHeader[0].style,
30837			divHeaderInner = divHeader.children('div'),
30838			divHeaderInnerStyle = divHeaderInner[0].style,
30839			divHeaderTable = divHeaderInner.children('table'),
30840			divBodyEl      = settings.nScrollBody,
30841			divBody        = $(divBodyEl),
30842			divBodyStyle   = divBodyEl.style,
30843			divFooter      = $(settings.nScrollFoot),
30844			divFooterInner = divFooter.children('div'),
30845			divFooterTable = divFooterInner.children('table'),
30846			header         = $(settings.nTHead),
30847			table          = $(settings.nTable),
30848			tableEl        = table[0],
30849			tableStyle     = tableEl.style,
30850			footer         = settings.nTFoot ? $(settings.nTFoot) : null,
30851			browser        = settings.oBrowser,
30852			ie67           = browser.bScrollOversize,
30853			dtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),
30854			headerTrgEls, footerTrgEls,
30855			headerSrcEls, footerSrcEls,
30856			headerCopy, footerCopy,
30857			headerWidths=[], footerWidths=[],
30858			headerContent=[], footerContent=[],
30859			idx, correction, sanityWidth,
30860			zeroOut = function(nSizer) {
30861				var style = nSizer.style;
30862				style.paddingTop = "0";
30863				style.paddingBottom = "0";
30864				style.borderTopWidth = "0";
30865				style.borderBottomWidth = "0";
30866				style.height = 0;
30867			};
30868
30869		// If the scrollbar visibility has changed from the last draw, we need to
30870		// adjust the column sizes as the table width will have changed to account
30871		// for the scrollbar
30872		var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
30873
30874		if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
30875			settings.scrollBarVis = scrollBarVis;
30876			_fnAdjustColumnSizing( settings );
30877			return; // adjust column sizing will call this function again
30878		}
30879		else {
30880			settings.scrollBarVis = scrollBarVis;
30881		}
30882
30883		/*
30884		 * 1. Re-create the table inside the scrolling div
30885		 */
30886
30887		// Remove the old minimised thead and tfoot elements in the inner table
30888		table.children('thead, tfoot').remove();
30889
30890		if ( footer ) {
30891			footerCopy = footer.clone().prependTo( table );
30892			footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
30893			footerSrcEls = footerCopy.find('tr');
30894		}
30895
30896		// Clone the current header and footer elements and then place it into the inner table
30897		headerCopy = header.clone().prependTo( table );
30898		headerTrgEls = header.find('tr'); // original header is in its own table
30899		headerSrcEls = headerCopy.find('tr');
30900		headerCopy.find('th, td').removeAttr('tabindex');
30901
30902
30903		/*
30904		 * 2. Take live measurements from the DOM - do not alter the DOM itself!
30905		 */
30906
30907		// Remove old sizing and apply the calculated column widths
30908		// Get the unique column headers in the newly created (cloned) header. We want to apply the
30909		// calculated sizes to this header
30910		if ( ! scrollX )
30911		{
30912			divBodyStyle.width = '100%';
30913			divHeader[0].style.width = '100%';
30914		}
30915
30916		$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
30917			idx = _fnVisibleToColumnIndex( settings, i );
30918			el.style.width = settings.aoColumns[idx].sWidth;
30919		} );
30920
30921		if ( footer ) {
30922			_fnApplyToChildren( function(n) {
30923				n.style.width = "";
30924			}, footerSrcEls );
30925		}
30926
30927		// Size the table as a whole
30928		sanityWidth = table.outerWidth();
30929		if ( scrollX === "" ) {
30930			// No x scrolling
30931			tableStyle.width = "100%";
30932
30933			// IE7 will make the width of the table when 100% include the scrollbar
30934			// - which is shouldn't. When there is a scrollbar we need to take this
30935			// into account.
30936			if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
30937				divBody.css('overflow-y') == "scroll")
30938			) {
30939				tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
30940			}
30941
30942			// Recalculate the sanity width
30943			sanityWidth = table.outerWidth();
30944		}
30945		else if ( scrollXInner !== "" ) {
30946			// legacy x scroll inner has been given - use it
30947			tableStyle.width = _fnStringToCss(scrollXInner);
30948
30949			// Recalculate the sanity width
30950			sanityWidth = table.outerWidth();
30951		}
30952
30953		// Hidden header should have zero height, so remove padding and borders. Then
30954		// set the width based on the real headers
30955
30956		// Apply all styles in one pass
30957		_fnApplyToChildren( zeroOut, headerSrcEls );
30958
30959		// Read all widths in next pass
30960		_fnApplyToChildren( function(nSizer) {
30961			headerContent.push( nSizer.innerHTML );
30962			headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
30963		}, headerSrcEls );
30964
30965		// Apply all widths in final pass
30966		_fnApplyToChildren( function(nToSize, i) {
30967			// Only apply widths to the DataTables detected header cells - this
30968			// prevents complex headers from having contradictory sizes applied
30969			if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
30970				nToSize.style.width = headerWidths[i];
30971			}
30972		}, headerTrgEls );
30973
30974		$(headerSrcEls).height(0);
30975
30976		/* Same again with the footer if we have one */
30977		if ( footer )
30978		{
30979			_fnApplyToChildren( zeroOut, footerSrcEls );
30980
30981			_fnApplyToChildren( function(nSizer) {
30982				footerContent.push( nSizer.innerHTML );
30983				footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
30984			}, footerSrcEls );
30985
30986			_fnApplyToChildren( function(nToSize, i) {
30987				nToSize.style.width = footerWidths[i];
30988			}, footerTrgEls );
30989
30990			$(footerSrcEls).height(0);
30991		}
30992
30993
30994		/*
30995		 * 3. Apply the measurements
30996		 */
30997
30998		// "Hide" the header and footer that we used for the sizing. We need to keep
30999		// the content of the cell so that the width applied to the header and body
31000		// both match, but we want to hide it completely. We want to also fix their
31001		// width to what they currently are
31002		_fnApplyToChildren( function(nSizer, i) {
31003			nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
31004			nSizer.style.width = headerWidths[i];
31005		}, headerSrcEls );
31006
31007		if ( footer )
31008		{
31009			_fnApplyToChildren( function(nSizer, i) {
31010				nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+footerContent[i]+'</div>';
31011				nSizer.style.width = footerWidths[i];
31012			}, footerSrcEls );
31013		}
31014
31015		// Sanity check that the table is of a sensible width. If not then we are going to get
31016		// misalignment - try to prevent this by not allowing the table to shrink below its min width
31017		if ( table.outerWidth() < sanityWidth )
31018		{
31019			// The min width depends upon if we have a vertical scrollbar visible or not */
31020			correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
31021				divBody.css('overflow-y') == "scroll")) ?
31022				sanityWidth+barWidth :
31023				sanityWidth;
31024
31025			// IE6/7 are a law unto themselves...
31026			if ( ie67 && (divBodyEl.scrollHeight >
31027				divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
31028			) {
31029				tableStyle.width = _fnStringToCss( correction-barWidth );
31030			}
31031
31032			// And give the user a warning that we've stopped the table getting too small
31033			if ( scrollX === "" || scrollXInner !== "" ) {
31034				_fnLog( settings, 1, 'Possible column misalignment', 6 );
31035			}
31036		}
31037		else
31038		{
31039			correction = '100%';
31040		}
31041
31042		// Apply to the container elements
31043		divBodyStyle.width = _fnStringToCss( correction );
31044		divHeaderStyle.width = _fnStringToCss( correction );
31045
31046		if ( footer ) {
31047			settings.nScrollFoot.style.width = _fnStringToCss( correction );
31048		}
31049
31050
31051		/*
31052		 * 4. Clean up
31053		 */
31054		if ( ! scrollY ) {
31055			/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
31056			 * the scrollbar height from the visible display, rather than adding it on. We need to
31057			 * set the height in order to sort this. Don't want to do it in any other browsers.
31058			 */
31059			if ( ie67 ) {
31060				divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
31061			}
31062		}
31063
31064		/* Finally set the width's of the header and footer tables */
31065		var iOuterWidth = table.outerWidth();
31066		divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
31067		divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
31068
31069		// Figure out if there are scrollbar present - if so then we need a the header and footer to
31070		// provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
31071		var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
31072		var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
31073		divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
31074
31075		if ( footer ) {
31076			divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
31077			divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
31078			divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
31079		}
31080
31081		// Correct DOM ordering for colgroup - comes before the thead
31082		table.children('colgroup').insertBefore( table.children('thead') );
31083
31084		/* Adjust the position of the header in case we loose the y-scrollbar */
31085		divBody.scroll();
31086
31087		// If sorting or filtering has occurred, jump the scrolling back to the top
31088		// only if we aren't holding the position
31089		if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
31090			divBodyEl.scrollTop = 0;
31091		}
31092	}
31093
31094
31095
31096	/**
31097	 * Apply a given function to the display child nodes of an element array (typically
31098	 * TD children of TR rows
31099	 *  @param {function} fn Method to apply to the objects
31100	 *  @param array {nodes} an1 List of elements to look through for display children
31101	 *  @param array {nodes} an2 Another list (identical structure to the first) - optional
31102	 *  @memberof DataTable#oApi
31103	 */
31104	function _fnApplyToChildren( fn, an1, an2 )
31105	{
31106		var index=0, i=0, iLen=an1.length;
31107		var nNode1, nNode2;
31108
31109		while ( i < iLen ) {
31110			nNode1 = an1[i].firstChild;
31111			nNode2 = an2 ? an2[i].firstChild : null;
31112
31113			while ( nNode1 ) {
31114				if ( nNode1.nodeType === 1 ) {
31115					if ( an2 ) {
31116						fn( nNode1, nNode2, index );
31117					}
31118					else {
31119						fn( nNode1, index );
31120					}
31121
31122					index++;
31123				}
31124
31125				nNode1 = nNode1.nextSibling;
31126				nNode2 = an2 ? nNode2.nextSibling : null;
31127			}
31128
31129			i++;
31130		}
31131	}
31132
31133
31134
31135	var __re_html_remove = /<.*?>/g;
31136
31137
31138	/**
31139	 * Calculate the width of columns for the table
31140	 *  @param {object} oSettings dataTables settings object
31141	 *  @memberof DataTable#oApi
31142	 */
31143	function _fnCalculateColumnWidths ( oSettings )
31144	{
31145		var
31146			table = oSettings.nTable,
31147			columns = oSettings.aoColumns,
31148			scroll = oSettings.oScroll,
31149			scrollY = scroll.sY,
31150			scrollX = scroll.sX,
31151			scrollXInner = scroll.sXInner,
31152			columnCount = columns.length,
31153			visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
31154			headerCells = $('th', oSettings.nTHead),
31155			tableWidthAttr = table.getAttribute('width'), // from DOM element
31156			tableContainer = table.parentNode,
31157			userInputs = false,
31158			i, column, columnIdx, width, outerWidth,
31159			browser = oSettings.oBrowser,
31160			ie67 = browser.bScrollOversize;
31161
31162		var styleWidth = table.style.width;
31163		if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
31164			tableWidthAttr = styleWidth;
31165		}
31166
31167		/* Convert any user input sizes into pixel sizes */
31168		for ( i=0 ; i<visibleColumns.length ; i++ ) {
31169			column = columns[ visibleColumns[i] ];
31170
31171			if ( column.sWidth !== null ) {
31172				column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
31173
31174				userInputs = true;
31175			}
31176		}
31177
31178		/* If the number of columns in the DOM equals the number that we have to
31179		 * process in DataTables, then we can use the offsets that are created by
31180		 * the web- browser. No custom sizes can be set in order for this to happen,
31181		 * nor scrolling used
31182		 */
31183		if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
31184			columnCount == _fnVisbleColumns( oSettings ) &&
31185			columnCount == headerCells.length
31186		) {
31187			for ( i=0 ; i<columnCount ; i++ ) {
31188				var colIdx = _fnVisibleToColumnIndex( oSettings, i );
31189
31190				if ( colIdx !== null ) {
31191					columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
31192				}
31193			}
31194		}
31195		else
31196		{
31197			// Otherwise construct a single row, worst case, table with the widest
31198			// node in the data, assign any user defined widths, then insert it into
31199			// the DOM and allow the browser to do all the hard work of calculating
31200			// table widths
31201			var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
31202				.css( 'visibility', 'hidden' )
31203				.removeAttr( 'id' );
31204
31205			// Clean up the table body
31206			tmpTable.find('tbody tr').remove();
31207			var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
31208
31209			// Clone the table header and footer - we can't use the header / footer
31210			// from the cloned table, since if scrolling is active, the table's
31211			// real header and footer are contained in different table tags
31212			tmpTable.find('thead, tfoot').remove();
31213			tmpTable
31214				.append( $(oSettings.nTHead).clone() )
31215				.append( $(oSettings.nTFoot).clone() );
31216
31217			// Remove any assigned widths from the footer (from scrolling)
31218			tmpTable.find('tfoot th, tfoot td').css('width', '');
31219
31220			// Apply custom sizing to the cloned header
31221			headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
31222
31223			for ( i=0 ; i<visibleColumns.length ; i++ ) {
31224				column = columns[ visibleColumns[i] ];
31225
31226				headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
31227					_fnStringToCss( column.sWidthOrig ) :
31228					'';
31229
31230				// For scrollX we need to force the column width otherwise the
31231				// browser will collapse it. If this width is smaller than the
31232				// width the column requires, then it will have no effect
31233				if ( column.sWidthOrig && scrollX ) {
31234					$( headerCells[i] ).append( $('<div/>').css( {
31235						width: column.sWidthOrig,
31236						margin: 0,
31237						padding: 0,
31238						border: 0,
31239						height: 1
31240					} ) );
31241				}
31242			}
31243
31244			// Find the widest cell for each column and put it into the table
31245			if ( oSettings.aoData.length ) {
31246				for ( i=0 ; i<visibleColumns.length ; i++ ) {
31247					columnIdx = visibleColumns[i];
31248					column = columns[ columnIdx ];
31249
31250					$( _fnGetWidestNode( oSettings, columnIdx ) )
31251						.clone( false )
31252						.append( column.sContentPadding )
31253						.appendTo( tr );
31254				}
31255			}
31256
31257			// Tidy the temporary table - remove name attributes so there aren't
31258			// duplicated in the dom (radio elements for example)
31259			$('[name]', tmpTable).removeAttr('name');
31260
31261			// Table has been built, attach to the document so we can work with it.
31262			// A holding element is used, positioned at the top of the container
31263			// with minimal height, so it has no effect on if the container scrolls
31264			// or not. Otherwise it might trigger scrolling when it actually isn't
31265			// needed
31266			var holder = $('<div/>').css( scrollX || scrollY ?
31267				{
31268					position: 'absolute',
31269					top: 0,
31270					left: 0,
31271					height: 1,
31272					right: 0,
31273					overflow: 'hidden'
31274				} :
31275				{}
31276			)
31277				.append( tmpTable )
31278				.appendTo( tableContainer );
31279
31280			// When scrolling (X or Y) we want to set the width of the table as
31281			// appropriate. However, when not scrolling leave the table width as it
31282			// is. This results in slightly different, but I think correct behaviour
31283			if ( scrollX && scrollXInner ) {
31284				tmpTable.width( scrollXInner );
31285			}
31286			else if ( scrollX ) {
31287				tmpTable.css( 'width', 'auto' );
31288				tmpTable.removeAttr('width');
31289
31290				// If there is no width attribute or style, then allow the table to
31291				// collapse
31292				if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
31293					tmpTable.width( tableContainer.clientWidth );
31294				}
31295			}
31296			else if ( scrollY ) {
31297				tmpTable.width( tableContainer.clientWidth );
31298			}
31299			else if ( tableWidthAttr ) {
31300				tmpTable.width( tableWidthAttr );
31301			}
31302
31303			// Get the width of each column in the constructed table - we need to
31304			// know the inner width (so it can be assigned to the other table's
31305			// cells) and the outer width so we can calculate the full width of the
31306			// table. This is safe since DataTables requires a unique cell for each
31307			// column, but if ever a header can span multiple columns, this will
31308			// need to be modified.
31309			var total = 0;
31310			for ( i=0 ; i<visibleColumns.length ; i++ ) {
31311				var cell = $(headerCells[i]);
31312				var border = cell.outerWidth() - cell.width();
31313
31314				// Use getBounding... where possible (not IE8-) because it can give
31315				// sub-pixel accuracy, which we then want to round up!
31316				var bounding = browser.bBounding ?
31317					Math.ceil( headerCells[i].getBoundingClientRect().width ) :
31318					cell.outerWidth();
31319
31320				// Total is tracked to remove any sub-pixel errors as the outerWidth
31321				// of the table might not equal the total given here (IE!).
31322				total += bounding;
31323
31324				// Width for each column to use
31325				columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
31326			}
31327
31328			table.style.width = _fnStringToCss( total );
31329
31330			// Finished with the table - ditch it
31331			holder.remove();
31332		}
31333
31334		// If there is a width attr, we want to attach an event listener which
31335		// allows the table sizing to automatically adjust when the window is
31336		// resized. Use the width attr rather than CSS, since we can't know if the
31337		// CSS is a relative value or absolute - DOM read is always px.
31338		if ( tableWidthAttr ) {
31339			table.style.width = _fnStringToCss( tableWidthAttr );
31340		}
31341
31342		if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
31343			var bindResize = function () {
31344				$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
31345					_fnAdjustColumnSizing( oSettings );
31346				} ) );
31347			};
31348
31349			// IE6/7 will crash if we bind a resize event handler on page load.
31350			// To be removed in 1.11 which drops IE6/7 support
31351			if ( ie67 ) {
31352				setTimeout( bindResize, 1000 );
31353			}
31354			else {
31355				bindResize();
31356			}
31357
31358			oSettings._reszEvt = true;
31359		}
31360	}
31361
31362
31363	/**
31364	 * Throttle the calls to a function. Arguments and context are maintained for
31365	 * the throttled function
31366	 *  @param {function} fn Function to be called
31367	 *  @param {int} [freq=200] call frequency in mS
31368	 *  @returns {function} wrapped function
31369	 *  @memberof DataTable#oApi
31370	 */
31371	var _fnThrottle = DataTable.util.throttle;
31372
31373
31374	/**
31375	 * Convert a CSS unit width to pixels (e.g. 2em)
31376	 *  @param {string} width width to be converted
31377	 *  @param {node} parent parent to get the with for (required for relative widths) - optional
31378	 *  @returns {int} width in pixels
31379	 *  @memberof DataTable#oApi
31380	 */
31381	function _fnConvertToWidth ( width, parent )
31382	{
31383		if ( ! width ) {
31384			return 0;
31385		}
31386
31387		var n = $('<div/>')
31388			.css( 'width', _fnStringToCss( width ) )
31389			.appendTo( parent || document.body );
31390
31391		var val = n[0].offsetWidth;
31392		n.remove();
31393
31394		return val;
31395	}
31396
31397
31398	/**
31399	 * Get the widest node
31400	 *  @param {object} settings dataTables settings object
31401	 *  @param {int} colIdx column of interest
31402	 *  @returns {node} widest table node
31403	 *  @memberof DataTable#oApi
31404	 */
31405	function _fnGetWidestNode( settings, colIdx )
31406	{
31407		var idx = _fnGetMaxLenString( settings, colIdx );
31408		if ( idx < 0 ) {
31409			return null;
31410		}
31411
31412		var data = settings.aoData[ idx ];
31413		return ! data.nTr ? // Might not have been created when deferred rendering
31414			$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
31415			data.anCells[ colIdx ];
31416	}
31417
31418
31419	/**
31420	 * Get the maximum strlen for each data column
31421	 *  @param {object} settings dataTables settings object
31422	 *  @param {int} colIdx column of interest
31423	 *  @returns {string} max string length for each column
31424	 *  @memberof DataTable#oApi
31425	 */
31426	function _fnGetMaxLenString( settings, colIdx )
31427	{
31428		var s, max=-1, maxIdx = -1;
31429
31430		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
31431			s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
31432			s = s.replace( __re_html_remove, '' );
31433			s = s.replace( /&nbsp;/g, ' ' );
31434
31435			if ( s.length > max ) {
31436				max = s.length;
31437				maxIdx = i;
31438			}
31439		}
31440
31441		return maxIdx;
31442	}
31443
31444
31445	/**
31446	 * Append a CSS unit (only if required) to a string
31447	 *  @param {string} value to css-ify
31448	 *  @returns {string} value with css unit
31449	 *  @memberof DataTable#oApi
31450	 */
31451	function _fnStringToCss( s )
31452	{
31453		if ( s === null ) {
31454			return '0px';
31455		}
31456
31457		if ( typeof s == 'number' ) {
31458			return s < 0 ?
31459				'0px' :
31460				s+'px';
31461		}
31462
31463		// Check it has a unit character already
31464		return s.match(/\d$/) ?
31465			s+'px' :
31466			s;
31467	}
31468
31469
31470
31471	function _fnSortFlatten ( settings )
31472	{
31473		var
31474			i, iLen, k, kLen,
31475			aSort = [],
31476			aiOrig = [],
31477			aoColumns = settings.aoColumns,
31478			aDataSort, iCol, sType, srcCol,
31479			fixed = settings.aaSortingFixed,
31480			fixedObj = $.isPlainObject( fixed ),
31481			nestedSort = [],
31482			add = function ( a ) {
31483				if ( a.length && ! $.isArray( a[0] ) ) {
31484					// 1D array
31485					nestedSort.push( a );
31486				}
31487				else {
31488					// 2D array
31489					$.merge( nestedSort, a );
31490				}
31491			};
31492
31493		// Build the sort array, with pre-fix and post-fix options if they have been
31494		// specified
31495		if ( $.isArray( fixed ) ) {
31496			add( fixed );
31497		}
31498
31499		if ( fixedObj && fixed.pre ) {
31500			add( fixed.pre );
31501		}
31502
31503		add( settings.aaSorting );
31504
31505		if (fixedObj && fixed.post ) {
31506			add( fixed.post );
31507		}
31508
31509		for ( i=0 ; i<nestedSort.length ; i++ )
31510		{
31511			srcCol = nestedSort[i][0];
31512			aDataSort = aoColumns[ srcCol ].aDataSort;
31513
31514			for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
31515			{
31516				iCol = aDataSort[k];
31517				sType = aoColumns[ iCol ].sType || 'string';
31518
31519				if ( nestedSort[i]._idx === undefined ) {
31520					nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
31521				}
31522
31523				aSort.push( {
31524					src:       srcCol,
31525					col:       iCol,
31526					dir:       nestedSort[i][1],
31527					index:     nestedSort[i]._idx,
31528					type:      sType,
31529					formatter: DataTable.ext.type.order[ sType+"-pre" ]
31530				} );
31531			}
31532		}
31533
31534		return aSort;
31535	}
31536
31537	/**
31538	 * Change the order of the table
31539	 *  @param {object} oSettings dataTables settings object
31540	 *  @memberof DataTable#oApi
31541	 *  @todo This really needs split up!
31542	 */
31543	function _fnSort ( oSettings )
31544	{
31545		var
31546			i, ien, iLen, j, jLen, k, kLen,
31547			sDataType, nTh,
31548			aiOrig = [],
31549			oExtSort = DataTable.ext.type.order,
31550			aoData = oSettings.aoData,
31551			aoColumns = oSettings.aoColumns,
31552			aDataSort, data, iCol, sType, oSort,
31553			formatters = 0,
31554			sortCol,
31555			displayMaster = oSettings.aiDisplayMaster,
31556			aSort;
31557
31558		// Resolve any column types that are unknown due to addition or invalidation
31559		// @todo Can this be moved into a 'data-ready' handler which is called when
31560		//   data is going to be used in the table?
31561		_fnColumnTypes( oSettings );
31562
31563		aSort = _fnSortFlatten( oSettings );
31564
31565		for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
31566			sortCol = aSort[i];
31567
31568			// Track if we can use the fast sort algorithm
31569			if ( sortCol.formatter ) {
31570				formatters++;
31571			}
31572
31573			// Load the data needed for the sort, for each cell
31574			_fnSortData( oSettings, sortCol.col );
31575		}
31576
31577		/* No sorting required if server-side or no sorting array */
31578		if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
31579		{
31580			// Create a value - key array of the current row positions such that we can use their
31581			// current position during the sort, if values match, in order to perform stable sorting
31582			for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
31583				aiOrig[ displayMaster[i] ] = i;
31584			}
31585
31586			/* Do the sort - here we want multi-column sorting based on a given data source (column)
31587			 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
31588			 * follow on it's own, but this is what we want (example two column sorting):
31589			 *  fnLocalSorting = function(a,b){
31590			 *    var iTest;
31591			 *    iTest = oSort['string-asc']('data11', 'data12');
31592			 *      if (iTest !== 0)
31593			 *        return iTest;
31594			 *    iTest = oSort['numeric-desc']('data21', 'data22');
31595			 *    if (iTest !== 0)
31596			 *      return iTest;
31597			 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
31598			 *  }
31599			 * Basically we have a test for each sorting column, if the data in that column is equal,
31600			 * test the next column. If all columns match, then we use a numeric sort on the row
31601			 * positions in the original data array to provide a stable sort.
31602			 *
31603			 * Note - I know it seems excessive to have two sorting methods, but the first is around
31604			 * 15% faster, so the second is only maintained for backwards compatibility with sorting
31605			 * methods which do not have a pre-sort formatting function.
31606			 */
31607			if ( formatters === aSort.length ) {
31608				// All sort types have formatting functions
31609				displayMaster.sort( function ( a, b ) {
31610					var
31611						x, y, k, test, sort,
31612						len=aSort.length,
31613						dataA = aoData[a]._aSortData,
31614						dataB = aoData[b]._aSortData;
31615
31616					for ( k=0 ; k<len ; k++ ) {
31617						sort = aSort[k];
31618
31619						x = dataA[ sort.col ];
31620						y = dataB[ sort.col ];
31621
31622						test = x<y ? -1 : x>y ? 1 : 0;
31623						if ( test !== 0 ) {
31624							return sort.dir === 'asc' ? test : -test;
31625						}
31626					}
31627
31628					x = aiOrig[a];
31629					y = aiOrig[b];
31630					return x<y ? -1 : x>y ? 1 : 0;
31631				} );
31632			}
31633			else {
31634				// Depreciated - remove in 1.11 (providing a plug-in option)
31635				// Not all sort types have formatting methods, so we have to call their sorting
31636				// methods.
31637				displayMaster.sort( function ( a, b ) {
31638					var
31639						x, y, k, l, test, sort, fn,
31640						len=aSort.length,
31641						dataA = aoData[a]._aSortData,
31642						dataB = aoData[b]._aSortData;
31643
31644					for ( k=0 ; k<len ; k++ ) {
31645						sort = aSort[k];
31646
31647						x = dataA[ sort.col ];
31648						y = dataB[ sort.col ];
31649
31650						fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
31651						test = fn( x, y );
31652						if ( test !== 0 ) {
31653							return test;
31654						}
31655					}
31656
31657					x = aiOrig[a];
31658					y = aiOrig[b];
31659					return x<y ? -1 : x>y ? 1 : 0;
31660				} );
31661			}
31662		}
31663
31664		/* Tell the draw function that we have sorted the data */
31665		oSettings.bSorted = true;
31666	}
31667
31668
31669	function _fnSortAria ( settings )
31670	{
31671		var label;
31672		var nextSort;
31673		var columns = settings.aoColumns;
31674		var aSort = _fnSortFlatten( settings );
31675		var oAria = settings.oLanguage.oAria;
31676
31677		// ARIA attributes - need to loop all columns, to update all (removing old
31678		// attributes as needed)
31679		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
31680		{
31681			var col = columns[i];
31682			var asSorting = col.asSorting;
31683			var sTitle = col.sTitle.replace( /<.*?>/g, "" );
31684			var th = col.nTh;
31685
31686			// IE7 is throwing an error when setting these properties with jQuery's
31687			// attr() and removeAttr() methods...
31688			th.removeAttribute('aria-sort');
31689
31690			/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
31691			if ( col.bSortable ) {
31692				if ( aSort.length > 0 && aSort[0].col == i ) {
31693					th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
31694					nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
31695				}
31696				else {
31697					nextSort = asSorting[0];
31698				}
31699
31700				label = sTitle + ( nextSort === "asc" ?
31701						oAria.sSortAscending :
31702						oAria.sSortDescending
31703				);
31704			}
31705			else {
31706				label = sTitle;
31707			}
31708
31709			th.setAttribute('aria-label', label);
31710		}
31711	}
31712
31713
31714	/**
31715	 * Function to run on user sort request
31716	 *  @param {object} settings dataTables settings object
31717	 *  @param {node} attachTo node to attach the handler to
31718	 *  @param {int} colIdx column sorting index
31719	 *  @param {boolean} [append=false] Append the requested sort to the existing
31720	 *    sort if true (i.e. multi-column sort)
31721	 *  @param {function} [callback] callback function
31722	 *  @memberof DataTable#oApi
31723	 */
31724	function _fnSortListener ( settings, colIdx, append, callback )
31725	{
31726		var col = settings.aoColumns[ colIdx ];
31727		var sorting = settings.aaSorting;
31728		var asSorting = col.asSorting;
31729		var nextSortIdx;
31730		var next = function ( a, overflow ) {
31731			var idx = a._idx;
31732			if ( idx === undefined ) {
31733				idx = $.inArray( a[1], asSorting );
31734			}
31735
31736			return idx+1 < asSorting.length ?
31737				idx+1 :
31738				overflow ?
31739					null :
31740					0;
31741		};
31742
31743		// Convert to 2D array if needed
31744		if ( typeof sorting[0] === 'number' ) {
31745			sorting = settings.aaSorting = [ sorting ];
31746		}
31747
31748		// If appending the sort then we are multi-column sorting
31749		if ( append && settings.oFeatures.bSortMulti ) {
31750			// Are we already doing some kind of sort on this column?
31751			var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
31752
31753			if ( sortIdx !== -1 ) {
31754				// Yes, modify the sort
31755				nextSortIdx = next( sorting[sortIdx], true );
31756
31757				if ( nextSortIdx === null && sorting.length === 1 ) {
31758					nextSortIdx = 0; // can't remove sorting completely
31759				}
31760
31761				if ( nextSortIdx === null ) {
31762					sorting.splice( sortIdx, 1 );
31763				}
31764				else {
31765					sorting[sortIdx][1] = asSorting[ nextSortIdx ];
31766					sorting[sortIdx]._idx = nextSortIdx;
31767				}
31768			}
31769			else {
31770				// No sort on this column yet
31771				sorting.push( [ colIdx, asSorting[0], 0 ] );
31772				sorting[sorting.length-1]._idx = 0;
31773			}
31774		}
31775		else if ( sorting.length && sorting[0][0] == colIdx ) {
31776			// Single column - already sorting on this column, modify the sort
31777			nextSortIdx = next( sorting[0] );
31778
31779			sorting.length = 1;
31780			sorting[0][1] = asSorting[ nextSortIdx ];
31781			sorting[0]._idx = nextSortIdx;
31782		}
31783		else {
31784			// Single column - sort only on this column
31785			sorting.length = 0;
31786			sorting.push( [ colIdx, asSorting[0] ] );
31787			sorting[0]._idx = 0;
31788		}
31789
31790		// Run the sort by calling a full redraw
31791		_fnReDraw( settings );
31792
31793		// callback used for async user interaction
31794		if ( typeof callback == 'function' ) {
31795			callback( settings );
31796		}
31797	}
31798
31799
31800	/**
31801	 * Attach a sort handler (click) to a node
31802	 *  @param {object} settings dataTables settings object
31803	 *  @param {node} attachTo node to attach the handler to
31804	 *  @param {int} colIdx column sorting index
31805	 *  @param {function} [callback] callback function
31806	 *  @memberof DataTable#oApi
31807	 */
31808	function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
31809	{
31810		var col = settings.aoColumns[ colIdx ];
31811
31812		_fnBindAction( attachTo, {}, function (e) {
31813			/* If the column is not sortable - don't to anything */
31814			if ( col.bSortable === false ) {
31815				return;
31816			}
31817
31818			// If processing is enabled use a timeout to allow the processing
31819			// display to be shown - otherwise to it synchronously
31820			if ( settings.oFeatures.bProcessing ) {
31821				_fnProcessingDisplay( settings, true );
31822
31823				setTimeout( function() {
31824					_fnSortListener( settings, colIdx, e.shiftKey, callback );
31825
31826					// In server-side processing, the draw callback will remove the
31827					// processing display
31828					if ( _fnDataSource( settings ) !== 'ssp' ) {
31829						_fnProcessingDisplay( settings, false );
31830					}
31831				}, 0 );
31832			}
31833			else {
31834				_fnSortListener( settings, colIdx, e.shiftKey, callback );
31835			}
31836		} );
31837	}
31838
31839
31840	/**
31841	 * Set the sorting classes on table's body, Note: it is safe to call this function
31842	 * when bSort and bSortClasses are false
31843	 *  @param {object} oSettings dataTables settings object
31844	 *  @memberof DataTable#oApi
31845	 */
31846	function _fnSortingClasses( settings )
31847	{
31848		var oldSort = settings.aLastSort;
31849		var sortClass = settings.oClasses.sSortColumn;
31850		var sort = _fnSortFlatten( settings );
31851		var features = settings.oFeatures;
31852		var i, ien, colIdx;
31853
31854		if ( features.bSort && features.bSortClasses ) {
31855			// Remove old sorting classes
31856			for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
31857				colIdx = oldSort[i].src;
31858
31859				// Remove column sorting
31860				$( _pluck( settings.aoData, 'anCells', colIdx ) )
31861					.removeClass( sortClass + (i<2 ? i+1 : 3) );
31862			}
31863
31864			// Add new column sorting
31865			for ( i=0, ien=sort.length ; i<ien ; i++ ) {
31866				colIdx = sort[i].src;
31867
31868				$( _pluck( settings.aoData, 'anCells', colIdx ) )
31869					.addClass( sortClass + (i<2 ? i+1 : 3) );
31870			}
31871		}
31872
31873		settings.aLastSort = sort;
31874	}
31875
31876
31877	// Get the data to sort a column, be it from cache, fresh (populating the
31878	// cache), or from a sort formatter
31879	function _fnSortData( settings, idx )
31880	{
31881		// Custom sorting function - provided by the sort data type
31882		var column = settings.aoColumns[ idx ];
31883		var customSort = DataTable.ext.order[ column.sSortDataType ];
31884		var customData;
31885
31886		if ( customSort ) {
31887			customData = customSort.call( settings.oInstance, settings, idx,
31888				_fnColumnIndexToVisible( settings, idx )
31889			);
31890		}
31891
31892		// Use / populate cache
31893		var row, cellData;
31894		var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
31895
31896		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
31897			row = settings.aoData[i];
31898
31899			if ( ! row._aSortData ) {
31900				row._aSortData = [];
31901			}
31902
31903			if ( ! row._aSortData[idx] || customSort ) {
31904				cellData = customSort ?
31905					customData[i] : // If there was a custom sort function, use data from there
31906					_fnGetCellData( settings, i, idx, 'sort' );
31907
31908				row._aSortData[ idx ] = formatter ?
31909					formatter( cellData ) :
31910					cellData;
31911			}
31912		}
31913	}
31914
31915
31916
31917	/**
31918	 * Save the state of a table
31919	 *  @param {object} oSettings dataTables settings object
31920	 *  @memberof DataTable#oApi
31921	 */
31922	function _fnSaveState ( settings )
31923	{
31924		if ( !settings.oFeatures.bStateSave || settings.bDestroying )
31925		{
31926			return;
31927		}
31928
31929		/* Store the interesting variables */
31930		var state = {
31931			time:    +new Date(),
31932			start:   settings._iDisplayStart,
31933			length:  settings._iDisplayLength,
31934			order:   $.extend( true, [], settings.aaSorting ),
31935			search:  _fnSearchToCamel( settings.oPreviousSearch ),
31936			columns: $.map( settings.aoColumns, function ( col, i ) {
31937				return {
31938					visible: col.bVisible,
31939					search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
31940				};
31941			} )
31942		};
31943
31944		_fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
31945
31946		settings.oSavedState = state;
31947		settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
31948	}
31949
31950
31951	/**
31952	 * Attempt to load a saved table state
31953	 *  @param {object} oSettings dataTables settings object
31954	 *  @param {object} oInit DataTables init object so we can override settings
31955	 *  @memberof DataTable#oApi
31956	 */
31957	function _fnLoadState ( settings, oInit )
31958	{
31959		var i, ien;
31960		var columns = settings.aoColumns;
31961
31962		if ( ! settings.oFeatures.bStateSave ) {
31963			return;
31964		}
31965
31966		var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
31967		if ( ! state || ! state.time ) {
31968			return;
31969		}
31970
31971		/* Allow custom and plug-in manipulation functions to alter the saved data set and
31972		 * cancelling of loading by returning false
31973		 */
31974		var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
31975		if ( $.inArray( false, abStateLoad ) !== -1 ) {
31976			return;
31977		}
31978
31979		/* Reject old data */
31980		var duration = settings.iStateDuration;
31981		if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
31982			return;
31983		}
31984
31985		// Number of columns have changed - all bets are off, no restore of settings
31986		if ( columns.length !== state.columns.length ) {
31987			return;
31988		}
31989
31990		// Store the saved state so it might be accessed at any time
31991		settings.oLoadedState = $.extend( true, {}, state );
31992
31993		// Restore key features - todo - for 1.11 this needs to be done by
31994		// subscribed events
31995		if ( state.start !== undefined ) {
31996			settings._iDisplayStart    = state.start;
31997			settings.iInitDisplayStart = state.start;
31998		}
31999		if ( state.length !== undefined ) {
32000			settings._iDisplayLength   = state.length;
32001		}
32002
32003		// Order
32004		if ( state.order !== undefined ) {
32005			settings.aaSorting = [];
32006			$.each( state.order, function ( i, col ) {
32007				settings.aaSorting.push( col[0] >= columns.length ?
32008					[ 0, col[1] ] :
32009					col
32010				);
32011			} );
32012		}
32013
32014		// Search
32015		if ( state.search !== undefined ) {
32016			$.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
32017		}
32018
32019		// Columns
32020		for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
32021			var col = state.columns[i];
32022
32023			// Visibility
32024			if ( col.visible !== undefined ) {
32025				columns[i].bVisible = col.visible;
32026			}
32027
32028			// Search
32029			if ( col.search !== undefined ) {
32030				$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
32031			}
32032		}
32033
32034		_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
32035	}
32036
32037
32038	/**
32039	 * Return the settings object for a particular table
32040	 *  @param {node} table table we are using as a dataTable
32041	 *  @returns {object} Settings object - or null if not found
32042	 *  @memberof DataTable#oApi
32043	 */
32044	function _fnSettingsFromNode ( table )
32045	{
32046		var settings = DataTable.settings;
32047		var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
32048
32049		return idx !== -1 ?
32050			settings[ idx ] :
32051			null;
32052	}
32053
32054
32055	/**
32056	 * Log an error message
32057	 *  @param {object} settings dataTables settings object
32058	 *  @param {int} level log error messages, or display them to the user
32059	 *  @param {string} msg error message
32060	 *  @param {int} tn Technical note id to get more information about the error.
32061	 *  @memberof DataTable#oApi
32062	 */
32063	function _fnLog( settings, level, msg, tn )
32064	{
32065		msg = 'DataTables warning: '+
32066			(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
32067
32068		if ( tn ) {
32069			msg += '. For more information about this error, please see '+
32070				'http://datatables.net/tn/'+tn;
32071		}
32072
32073		if ( ! level  ) {
32074			// Backwards compatibility pre 1.10
32075			var ext = DataTable.ext;
32076			var type = ext.sErrMode || ext.errMode;
32077
32078			if ( settings ) {
32079				_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
32080			}
32081
32082			if ( type == 'alert' ) {
32083				alert( msg );
32084			}
32085			else if ( type == 'throw' ) {
32086				throw new Error(msg);
32087			}
32088			else if ( typeof type == 'function' ) {
32089				type( settings, tn, msg );
32090			}
32091		}
32092		else if ( window.console && console.log ) {
32093			console.log( msg );
32094		}
32095	}
32096
32097
32098	/**
32099	 * See if a property is defined on one object, if so assign it to the other object
32100	 *  @param {object} ret target object
32101	 *  @param {object} src source object
32102	 *  @param {string} name property
32103	 *  @param {string} [mappedName] name to map too - optional, name used if not given
32104	 *  @memberof DataTable#oApi
32105	 */
32106	function _fnMap( ret, src, name, mappedName )
32107	{
32108		if ( $.isArray( name ) ) {
32109			$.each( name, function (i, val) {
32110				if ( $.isArray( val ) ) {
32111					_fnMap( ret, src, val[0], val[1] );
32112				}
32113				else {
32114					_fnMap( ret, src, val );
32115				}
32116			} );
32117
32118			return;
32119		}
32120
32121		if ( mappedName === undefined ) {
32122			mappedName = name;
32123		}
32124
32125		if ( src[name] !== undefined ) {
32126			ret[mappedName] = src[name];
32127		}
32128	}
32129
32130
32131	/**
32132	 * Extend objects - very similar to jQuery.extend, but deep copy objects, and
32133	 * shallow copy arrays. The reason we need to do this, is that we don't want to
32134	 * deep copy array init values (such as aaSorting) since the dev wouldn't be
32135	 * able to override them, but we do want to deep copy arrays.
32136	 *  @param {object} out Object to extend
32137	 *  @param {object} extender Object from which the properties will be applied to
32138	 *      out
32139	 *  @param {boolean} breakRefs If true, then arrays will be sliced to take an
32140	 *      independent copy with the exception of the `data` or `aaData` parameters
32141	 *      if they are present. This is so you can pass in a collection to
32142	 *      DataTables and have that used as your data source without breaking the
32143	 *      references
32144	 *  @returns {object} out Reference, just for convenience - out === the return.
32145	 *  @memberof DataTable#oApi
32146	 *  @todo This doesn't take account of arrays inside the deep copied objects.
32147	 */
32148	function _fnExtend( out, extender, breakRefs )
32149	{
32150		var val;
32151
32152		for ( var prop in extender ) {
32153			if ( extender.hasOwnProperty(prop) ) {
32154				val = extender[prop];
32155
32156				if ( $.isPlainObject( val ) ) {
32157					if ( ! $.isPlainObject( out[prop] ) ) {
32158						out[prop] = {};
32159					}
32160					$.extend( true, out[prop], val );
32161				}
32162				else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
32163					out[prop] = val.slice();
32164				}
32165				else {
32166					out[prop] = val;
32167				}
32168			}
32169		}
32170
32171		return out;
32172	}
32173
32174
32175	/**
32176	 * Bind an event handers to allow a click or return key to activate the callback.
32177	 * This is good for accessibility since a return on the keyboard will have the
32178	 * same effect as a click, if the element has focus.
32179	 *  @param {element} n Element to bind the action to
32180	 *  @param {object} oData Data object to pass to the triggered function
32181	 *  @param {function} fn Callback function for when the event is triggered
32182	 *  @memberof DataTable#oApi
32183	 */
32184	function _fnBindAction( n, oData, fn )
32185	{
32186		$(n)
32187			.bind( 'click.DT', oData, function (e) {
32188				n.blur(); // Remove focus outline for mouse users
32189				fn(e);
32190			} )
32191			.bind( 'keypress.DT', oData, function (e){
32192				if ( e.which === 13 ) {
32193					e.preventDefault();
32194					fn(e);
32195				}
32196			} )
32197			.bind( 'selectstart.DT', function () {
32198				/* Take the brutal approach to cancelling text selection */
32199				return false;
32200			} );
32201	}
32202
32203
32204	/**
32205	 * Register a callback function. Easily allows a callback function to be added to
32206	 * an array store of callback functions that can then all be called together.
32207	 *  @param {object} oSettings dataTables settings object
32208	 *  @param {string} sStore Name of the array storage for the callbacks in oSettings
32209	 *  @param {function} fn Function to be called back
32210	 *  @param {string} sName Identifying name for the callback (i.e. a label)
32211	 *  @memberof DataTable#oApi
32212	 */
32213	function _fnCallbackReg( oSettings, sStore, fn, sName )
32214	{
32215		if ( fn )
32216		{
32217			oSettings[sStore].push( {
32218				"fn": fn,
32219				"sName": sName
32220			} );
32221		}
32222	}
32223
32224
32225	/**
32226	 * Fire callback functions and trigger events. Note that the loop over the
32227	 * callback array store is done backwards! Further note that you do not want to
32228	 * fire off triggers in time sensitive applications (for example cell creation)
32229	 * as its slow.
32230	 *  @param {object} settings dataTables settings object
32231	 *  @param {string} callbackArr Name of the array storage for the callbacks in
32232	 *      oSettings
32233	 *  @param {string} eventName Name of the jQuery custom event to trigger. If
32234	 *      null no trigger is fired
32235	 *  @param {array} args Array of arguments to pass to the callback function /
32236	 *      trigger
32237	 *  @memberof DataTable#oApi
32238	 */
32239	function _fnCallbackFire( settings, callbackArr, eventName, args )
32240	{
32241		var ret = [];
32242
32243		if ( callbackArr ) {
32244			ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
32245				return val.fn.apply( settings.oInstance, args );
32246			} );
32247		}
32248
32249		if ( eventName !== null ) {
32250			var e = $.Event( eventName+'.dt' );
32251
32252			$(settings.nTable).trigger( e, args );
32253
32254			ret.push( e.result );
32255		}
32256
32257		return ret;
32258	}
32259
32260
32261	function _fnLengthOverflow ( settings )
32262	{
32263		var
32264			start = settings._iDisplayStart,
32265			end = settings.fnDisplayEnd(),
32266			len = settings._iDisplayLength;
32267
32268		/* If we have space to show extra rows (backing up from the end point - then do so */
32269		if ( start >= end )
32270		{
32271			start = end - len;
32272		}
32273
32274		// Keep the start record on the current page
32275		start -= (start % len);
32276
32277		if ( len === -1 || start < 0 )
32278		{
32279			start = 0;
32280		}
32281
32282		settings._iDisplayStart = start;
32283	}
32284
32285
32286	function _fnRenderer( settings, type )
32287	{
32288		var renderer = settings.renderer;
32289		var host = DataTable.ext.renderer[type];
32290
32291		if ( $.isPlainObject( renderer ) && renderer[type] ) {
32292			// Specific renderer for this type. If available use it, otherwise use
32293			// the default.
32294			return host[renderer[type]] || host._;
32295		}
32296		else if ( typeof renderer === 'string' ) {
32297			// Common renderer - if there is one available for this type use it,
32298			// otherwise use the default
32299			return host[renderer] || host._;
32300		}
32301
32302		// Use the default
32303		return host._;
32304	}
32305
32306
32307	/**
32308	 * Detect the data source being used for the table. Used to simplify the code
32309	 * a little (ajax) and to make it compress a little smaller.
32310	 *
32311	 *  @param {object} settings dataTables settings object
32312	 *  @returns {string} Data source
32313	 *  @memberof DataTable#oApi
32314	 */
32315	function _fnDataSource ( settings )
32316	{
32317		if ( settings.oFeatures.bServerSide ) {
32318			return 'ssp';
32319		}
32320		else if ( settings.ajax || settings.sAjaxSource ) {
32321			return 'ajax';
32322		}
32323		return 'dom';
32324	}
32325
32326
32327
32328
32329	/**
32330	 * Computed structure of the DataTables API, defined by the options passed to
32331	 * `DataTable.Api.register()` when building the API.
32332	 *
32333	 * The structure is built in order to speed creation and extension of the Api
32334	 * objects since the extensions are effectively pre-parsed.
32335	 *
32336	 * The array is an array of objects with the following structure, where this
32337	 * base array represents the Api prototype base:
32338	 *
32339	 *     [
32340	 *       {
32341	 *         name:      'data'                -- string   - Property name
32342	 *         val:       function () {},       -- function - Api method (or undefined if just an object
32343	 *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
32344	 *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
32345	 *       },
32346	 *       {
32347	 *         name:     'row'
32348	 *         val:       {},
32349	 *         methodExt: [ ... ],
32350	 *         propExt:   [
32351	 *           {
32352	 *             name:      'data'
32353	 *             val:       function () {},
32354	 *             methodExt: [ ... ],
32355	 *             propExt:   [ ... ]
32356	 *           },
32357	 *           ...
32358	 *         ]
32359	 *       }
32360	 *     ]
32361	 *
32362	 * @type {Array}
32363	 * @ignore
32364	 */
32365	var __apiStruct = [];
32366
32367
32368	/**
32369	 * `Array.prototype` reference.
32370	 *
32371	 * @type object
32372	 * @ignore
32373	 */
32374	var __arrayProto = Array.prototype;
32375
32376
32377	/**
32378	 * Abstraction for `context` parameter of the `Api` constructor to allow it to
32379	 * take several different forms for ease of use.
32380	 *
32381	 * Each of the input parameter types will be converted to a DataTables settings
32382	 * object where possible.
32383	 *
32384	 * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one
32385	 *   of:
32386	 *
32387	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
32388	 *     with be found and used.
32389	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
32390	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
32391	 *   * `object` - DataTables settings object
32392	 *   * `DataTables.Api` - API instance
32393	 * @return {array|null} Matching DataTables settings objects. `null` or
32394	 *   `undefined` is returned if no matching DataTable is found.
32395	 * @ignore
32396	 */
32397	var _toSettings = function ( mixed )
32398	{
32399		var idx, jq;
32400		var settings = DataTable.settings;
32401		var tables = $.map( settings, function (el, i) {
32402			return el.nTable;
32403		} );
32404
32405		if ( ! mixed ) {
32406			return [];
32407		}
32408		else if ( mixed.nTable && mixed.oApi ) {
32409			// DataTables settings object
32410			return [ mixed ];
32411		}
32412		else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
32413			// Table node
32414			idx = $.inArray( mixed, tables );
32415			return idx !== -1 ? [ settings[idx] ] : null;
32416		}
32417		else if ( mixed && typeof mixed.settings === 'function' ) {
32418			return mixed.settings().toArray();
32419		}
32420		else if ( typeof mixed === 'string' ) {
32421			// jQuery selector
32422			jq = $(mixed);
32423		}
32424		else if ( mixed instanceof $ ) {
32425			// jQuery object (also DataTables instance)
32426			jq = mixed;
32427		}
32428
32429		if ( jq ) {
32430			return jq.map( function(i) {
32431				idx = $.inArray( this, tables );
32432				return idx !== -1 ? settings[idx] : null;
32433			} ).toArray();
32434		}
32435	};
32436
32437
32438	/**
32439	 * DataTables API class - used to control and interface with  one or more
32440	 * DataTables enhanced tables.
32441	 *
32442	 * The API class is heavily based on jQuery, presenting a chainable interface
32443	 * that you can use to interact with tables. Each instance of the API class has
32444	 * a "context" - i.e. the tables that it will operate on. This could be a single
32445	 * table, all tables on a page or a sub-set thereof.
32446	 *
32447	 * Additionally the API is designed to allow you to easily work with the data in
32448	 * the tables, retrieving and manipulating it as required. This is done by
32449	 * presenting the API class as an array like interface. The contents of the
32450	 * array depend upon the actions requested by each method (for example
32451	 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
32452	 * return an array of objects or arrays depending upon your table's
32453	 * configuration). The API object has a number of array like methods (`push`,
32454	 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
32455	 * `unique` etc) to assist your working with the data held in a table.
32456	 *
32457	 * Most methods (those which return an Api instance) are chainable, which means
32458	 * the return from a method call also has all of the methods available that the
32459	 * top level object had. For example, these two calls are equivalent:
32460	 *
32461	 *     // Not chained
32462	 *     api.row.add( {...} );
32463	 *     api.draw();
32464	 *
32465	 *     // Chained
32466	 *     api.row.add( {...} ).draw();
32467	 *
32468	 * @class DataTable.Api
32469	 * @param {array|object|string|jQuery} context DataTable identifier. This is
32470	 *   used to define which DataTables enhanced tables this API will operate on.
32471	 *   Can be one of:
32472	 *
32473	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
32474	 *     with be found and used.
32475	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
32476	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
32477	 *   * `object` - DataTables settings object
32478	 * @param {array} [data] Data to initialise the Api instance with.
32479	 *
32480	 * @example
32481	 *   // Direct initialisation during DataTables construction
32482	 *   var api = $('#example').DataTable();
32483	 *
32484	 * @example
32485	 *   // Initialisation using a DataTables jQuery object
32486	 *   var api = $('#example').dataTable().api();
32487	 *
32488	 * @example
32489	 *   // Initialisation as a constructor
32490	 *   var api = new $.fn.DataTable.Api( 'table.dataTable' );
32491	 */
32492	_Api = function ( context, data )
32493	{
32494		if ( ! (this instanceof _Api) ) {
32495			return new _Api( context, data );
32496		}
32497
32498		var settings = [];
32499		var ctxSettings = function ( o ) {
32500			var a = _toSettings( o );
32501			if ( a ) {
32502				settings = settings.concat( a );
32503			}
32504		};
32505
32506		if ( $.isArray( context ) ) {
32507			for ( var i=0, ien=context.length ; i<ien ; i++ ) {
32508				ctxSettings( context[i] );
32509			}
32510		}
32511		else {
32512			ctxSettings( context );
32513		}
32514
32515		// Remove duplicates
32516		this.context = _unique( settings );
32517
32518		// Initial data
32519		if ( data ) {
32520			$.merge( this, data );
32521		}
32522
32523		// selector
32524		this.selector = {
32525			rows: null,
32526			cols: null,
32527			opts: null
32528		};
32529
32530		_Api.extend( this, this, __apiStruct );
32531	};
32532
32533	DataTable.Api = _Api;
32534
32535	// Don't destroy the existing prototype, just extend it. Required for jQuery 2's
32536	// isPlainObject.
32537	$.extend( _Api.prototype, {
32538		any: function ()
32539		{
32540			return this.count() !== 0;
32541		},
32542
32543
32544		concat:  __arrayProto.concat,
32545
32546
32547		context: [], // array of table settings objects
32548
32549
32550		count: function ()
32551		{
32552			return this.flatten().length;
32553		},
32554
32555
32556		each: function ( fn )
32557		{
32558			for ( var i=0, ien=this.length ; i<ien; i++ ) {
32559				fn.call( this, this[i], i, this );
32560			}
32561
32562			return this;
32563		},
32564
32565
32566		eq: function ( idx )
32567		{
32568			var ctx = this.context;
32569
32570			return ctx.length > idx ?
32571				new _Api( ctx[idx], this[idx] ) :
32572				null;
32573		},
32574
32575
32576		filter: function ( fn )
32577		{
32578			var a = [];
32579
32580			if ( __arrayProto.filter ) {
32581				a = __arrayProto.filter.call( this, fn, this );
32582			}
32583			else {
32584				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
32585				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
32586					if ( fn.call( this, this[i], i, this ) ) {
32587						a.push( this[i] );
32588					}
32589				}
32590			}
32591
32592			return new _Api( this.context, a );
32593		},
32594
32595
32596		flatten: function ()
32597		{
32598			var a = [];
32599			return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
32600		},
32601
32602
32603		join:    __arrayProto.join,
32604
32605
32606		indexOf: __arrayProto.indexOf || function (obj, start)
32607		{
32608			for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
32609				if ( this[i] === obj ) {
32610					return i;
32611				}
32612			}
32613			return -1;
32614		},
32615
32616		iterator: function ( flatten, type, fn, alwaysNew ) {
32617			var
32618				a = [], ret,
32619				i, ien, j, jen,
32620				context = this.context,
32621				rows, items, item,
32622				selector = this.selector;
32623
32624			// Argument shifting
32625			if ( typeof flatten === 'string' ) {
32626				alwaysNew = fn;
32627				fn = type;
32628				type = flatten;
32629				flatten = false;
32630			}
32631
32632			for ( i=0, ien=context.length ; i<ien ; i++ ) {
32633				var apiInst = new _Api( context[i] );
32634
32635				if ( type === 'table' ) {
32636					ret = fn.call( apiInst, context[i], i );
32637
32638					if ( ret !== undefined ) {
32639						a.push( ret );
32640					}
32641				}
32642				else if ( type === 'columns' || type === 'rows' ) {
32643					// this has same length as context - one entry for each table
32644					ret = fn.call( apiInst, context[i], this[i], i );
32645
32646					if ( ret !== undefined ) {
32647						a.push( ret );
32648					}
32649				}
32650				else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
32651					// columns and rows share the same structure.
32652					// 'this' is an array of column indexes for each context
32653					items = this[i];
32654
32655					if ( type === 'column-rows' ) {
32656						rows = _selector_row_indexes( context[i], selector.opts );
32657					}
32658
32659					for ( j=0, jen=items.length ; j<jen ; j++ ) {
32660						item = items[j];
32661
32662						if ( type === 'cell' ) {
32663							ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
32664						}
32665						else {
32666							ret = fn.call( apiInst, context[i], item, i, j, rows );
32667						}
32668
32669						if ( ret !== undefined ) {
32670							a.push( ret );
32671						}
32672					}
32673				}
32674			}
32675
32676			if ( a.length || alwaysNew ) {
32677				var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
32678				var apiSelector = api.selector;
32679				apiSelector.rows = selector.rows;
32680				apiSelector.cols = selector.cols;
32681				apiSelector.opts = selector.opts;
32682				return api;
32683			}
32684			return this;
32685		},
32686
32687
32688		lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
32689		{
32690			// Bit cheeky...
32691			return this.indexOf.apply( this.toArray.reverse(), arguments );
32692		},
32693
32694
32695		length:  0,
32696
32697
32698		map: function ( fn )
32699		{
32700			var a = [];
32701
32702			if ( __arrayProto.map ) {
32703				a = __arrayProto.map.call( this, fn, this );
32704			}
32705			else {
32706				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
32707				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
32708					a.push( fn.call( this, this[i], i ) );
32709				}
32710			}
32711
32712			return new _Api( this.context, a );
32713		},
32714
32715
32716		pluck: function ( prop )
32717		{
32718			return this.map( function ( el ) {
32719				return el[ prop ];
32720			} );
32721		},
32722
32723		pop:     __arrayProto.pop,
32724
32725
32726		push:    __arrayProto.push,
32727
32728
32729		// Does not return an API instance
32730		reduce: __arrayProto.reduce || function ( fn, init )
32731		{
32732			return _fnReduce( this, fn, init, 0, this.length, 1 );
32733		},
32734
32735
32736		reduceRight: __arrayProto.reduceRight || function ( fn, init )
32737		{
32738			return _fnReduce( this, fn, init, this.length-1, -1, -1 );
32739		},
32740
32741
32742		reverse: __arrayProto.reverse,
32743
32744
32745		// Object with rows, columns and opts
32746		selector: null,
32747
32748
32749		shift:   __arrayProto.shift,
32750
32751
32752		sort:    __arrayProto.sort, // ? name - order?
32753
32754
32755		splice:  __arrayProto.splice,
32756
32757
32758		toArray: function ()
32759		{
32760			return __arrayProto.slice.call( this );
32761		},
32762
32763
32764		to$: function ()
32765		{
32766			return $( this );
32767		},
32768
32769
32770		toJQuery: function ()
32771		{
32772			return $( this );
32773		},
32774
32775
32776		unique: function ()
32777		{
32778			return new _Api( this.context, _unique(this) );
32779		},
32780
32781
32782		unshift: __arrayProto.unshift
32783	} );
32784
32785
32786	_Api.extend = function ( scope, obj, ext )
32787	{
32788		// Only extend API instances and static properties of the API
32789		if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
32790			return;
32791		}
32792
32793		var
32794			i, ien,
32795			j, jen,
32796			struct, inner,
32797			methodScoping = function ( scope, fn, struc ) {
32798				return function () {
32799					var ret = fn.apply( scope, arguments );
32800
32801					// Method extension
32802					_Api.extend( ret, ret, struc.methodExt );
32803					return ret;
32804				};
32805			};
32806
32807		for ( i=0, ien=ext.length ; i<ien ; i++ ) {
32808			struct = ext[i];
32809
32810			// Value
32811			obj[ struct.name ] = typeof struct.val === 'function' ?
32812				methodScoping( scope, struct.val, struct ) :
32813				$.isPlainObject( struct.val ) ?
32814					{} :
32815					struct.val;
32816
32817			obj[ struct.name ].__dt_wrapper = true;
32818
32819			// Property extension
32820			_Api.extend( scope, obj[ struct.name ], struct.propExt );
32821		}
32822	};
32823
32824
32825	// @todo - Is there need for an augment function?
32826	// _Api.augment = function ( inst, name )
32827	// {
32828	// 	// Find src object in the structure from the name
32829	// 	var parts = name.split('.');
32830
32831	// 	_Api.extend( inst, obj );
32832	// };
32833
32834
32835	//     [
32836	//       {
32837	//         name:      'data'                -- string   - Property name
32838	//         val:       function () {},       -- function - Api method (or undefined if just an object
32839	//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
32840	//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
32841	//       },
32842	//       {
32843	//         name:     'row'
32844	//         val:       {},
32845	//         methodExt: [ ... ],
32846	//         propExt:   [
32847	//           {
32848	//             name:      'data'
32849	//             val:       function () {},
32850	//             methodExt: [ ... ],
32851	//             propExt:   [ ... ]
32852	//           },
32853	//           ...
32854	//         ]
32855	//       }
32856	//     ]
32857
32858	_Api.register = _api_register = function ( name, val )
32859	{
32860		if ( $.isArray( name ) ) {
32861			for ( var j=0, jen=name.length ; j<jen ; j++ ) {
32862				_Api.register( name[j], val );
32863			}
32864			return;
32865		}
32866
32867		var
32868			i, ien,
32869			heir = name.split('.'),
32870			struct = __apiStruct,
32871			key, method;
32872
32873		var find = function ( src, name ) {
32874			for ( var i=0, ien=src.length ; i<ien ; i++ ) {
32875				if ( src[i].name === name ) {
32876					return src[i];
32877				}
32878			}
32879			return null;
32880		};
32881
32882		for ( i=0, ien=heir.length ; i<ien ; i++ ) {
32883			method = heir[i].indexOf('()') !== -1;
32884			key = method ?
vendor: 42,192 bytes, lines 32885-34495
32885				heir[i].replace('()', '') :
32886				heir[i];
32887
32888			var src = find( struct, key );
32889			if ( ! src ) {
32890				src = {
32891					name:      key,
32892					val:       {},
32893					methodExt: [],
32894					propExt:   []
32895				};
32896				struct.push( src );
32897			}
32898
32899			if ( i === ien-1 ) {
32900				src.val = val;
32901			}
32902			else {
32903				struct = method ?
32904					src.methodExt :
32905					src.propExt;
32906			}
32907		}
32908	};
32909
32910
32911	_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
32912		_Api.register( pluralName, val );
32913
32914		_Api.register( singularName, function () {
32915			var ret = val.apply( this, arguments );
32916
32917			if ( ret === this ) {
32918				// Returned item is the API instance that was passed in, return it
32919				return this;
32920			}
32921			else if ( ret instanceof _Api ) {
32922				// New API instance returned, want the value from the first item
32923				// in the returned array for the singular result.
32924				return ret.length ?
32925					$.isArray( ret[0] ) ?
32926						new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
32927						ret[0] :
32928					undefined;
32929			}
32930
32931			// Non-API return - just fire it back
32932			return ret;
32933		} );
32934	};
32935
32936
32937	/**
32938	 * Selector for HTML tables. Apply the given selector to the give array of
32939	 * DataTables settings objects.
32940	 *
32941	 * @param {string|integer} [selector] jQuery selector string or integer
32942	 * @param  {array} Array of DataTables settings objects to be filtered
32943	 * @return {array}
32944	 * @ignore
32945	 */
32946	var __table_selector = function ( selector, a )
32947	{
32948		// Integer is used to pick out a table by index
32949		if ( typeof selector === 'number' ) {
32950			return [ a[ selector ] ];
32951		}
32952
32953		// Perform a jQuery selector on the table nodes
32954		var nodes = $.map( a, function (el, i) {
32955			return el.nTable;
32956		} );
32957
32958		return $(nodes)
32959			.filter( selector )
32960			.map( function (i) {
32961				// Need to translate back from the table node to the settings
32962				var idx = $.inArray( this, nodes );
32963				return a[ idx ];
32964			} )
32965			.toArray();
32966	};
32967
32968
32969
32970	/**
32971	 * Context selector for the API's context (i.e. the tables the API instance
32972	 * refers to.
32973	 *
32974	 * @name    DataTable.Api#tables
32975	 * @param {string|integer} [selector] Selector to pick which tables the iterator
32976	 *   should operate on. If not given, all tables in the current context are
32977	 *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to
32978	 *   select multiple tables or as an integer to select a single table.
32979	 * @returns {DataTable.Api} Returns a new API instance if a selector is given.
32980	 */
32981	_api_register( 'tables()', function ( selector ) {
32982		// A new instance is created if there was a selector specified
32983		return selector ?
32984			new _Api( __table_selector( selector, this.context ) ) :
32985			this;
32986	} );
32987
32988
32989	_api_register( 'table()', function ( selector ) {
32990		var tables = this.tables( selector );
32991		var ctx = tables.context;
32992
32993		// Truncate to the first matched table
32994		return ctx.length ?
32995			new _Api( ctx[0] ) :
32996			tables;
32997	} );
32998
32999
33000	_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
33001		return this.iterator( 'table', function ( ctx ) {
33002			return ctx.nTable;
33003		}, 1 );
33004	} );
33005
33006
33007	_api_registerPlural( 'tables().body()', 'table().body()' , function () {
33008		return this.iterator( 'table', function ( ctx ) {
33009			return ctx.nTBody;
33010		}, 1 );
33011	} );
33012
33013
33014	_api_registerPlural( 'tables().header()', 'table().header()' , function () {
33015		return this.iterator( 'table', function ( ctx ) {
33016			return ctx.nTHead;
33017		}, 1 );
33018	} );
33019
33020
33021	_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
33022		return this.iterator( 'table', function ( ctx ) {
33023			return ctx.nTFoot;
33024		}, 1 );
33025	} );
33026
33027
33028	_api_registerPlural( 'tables().containers()', 'table().container()' , function () {
33029		return this.iterator( 'table', function ( ctx ) {
33030			return ctx.nTableWrapper;
33031		}, 1 );
33032	} );
33033
33034
33035
33036	/**
33037	 * Redraw the tables in the current context.
33038	 */
33039	_api_register( 'draw()', function ( paging ) {
33040		return this.iterator( 'table', function ( settings ) {
33041			if ( paging === 'page' ) {
33042				_fnDraw( settings );
33043			}
33044			else {
33045				if ( typeof paging === 'string' ) {
33046					paging = paging === 'full-hold' ?
33047						false :
33048						true;
33049				}
33050
33051				_fnReDraw( settings, paging===false );
33052			}
33053		} );
33054	} );
33055
33056
33057
33058	/**
33059	 * Get the current page index.
33060	 *
33061	 * @return {integer} Current page index (zero based)
33062	 *//**
33063	 * Set the current page.
33064	 *
33065	 * Note that if you attempt to show a page which does not exist, DataTables will
33066	 * not throw an error, but rather reset the paging.
33067	 *
33068	 * @param {integer|string} action The paging action to take. This can be one of:
33069	 *  * `integer` - The page index to jump to
33070	 *  * `string` - An action to take:
33071	 *    * `first` - Jump to first page.
33072	 *    * `next` - Jump to the next page
33073	 *    * `previous` - Jump to previous page
33074	 *    * `last` - Jump to the last page.
33075	 * @returns {DataTables.Api} this
33076	 */
33077	_api_register( 'page()', function ( action ) {
33078		if ( action === undefined ) {
33079			return this.page.info().page; // not an expensive call
33080		}
33081
33082		// else, have an action to take on all tables
33083		return this.iterator( 'table', function ( settings ) {
33084			_fnPageChange( settings, action );
33085		} );
33086	} );
33087
33088
33089	/**
33090	 * Paging information for the first table in the current context.
33091	 *
33092	 * If you require paging information for another table, use the `table()` method
33093	 * with a suitable selector.
33094	 *
33095	 * @return {object} Object with the following properties set:
33096	 *  * `page` - Current page index (zero based - i.e. the first page is `0`)
33097	 *  * `pages` - Total number of pages
33098	 *  * `start` - Display index for the first record shown on the current page
33099	 *  * `end` - Display index for the last record shown on the current page
33100	 *  * `length` - Display length (number of records). Note that generally `start
33101	 *    + length = end`, but this is not always true, for example if there are
33102	 *    only 2 records to show on the final page, with a length of 10.
33103	 *  * `recordsTotal` - Full data set length
33104	 *  * `recordsDisplay` - Data set length once the current filtering criterion
33105	 *    are applied.
33106	 */
33107	_api_register( 'page.info()', function ( action ) {
33108		if ( this.context.length === 0 ) {
33109			return undefined;
33110		}
33111
33112		var
33113			settings   = this.context[0],
33114			start      = settings._iDisplayStart,
33115			len        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
33116			visRecords = settings.fnRecordsDisplay(),
33117			all        = len === -1;
33118
33119		return {
33120			"page":           all ? 0 : Math.floor( start / len ),
33121			"pages":          all ? 1 : Math.ceil( visRecords / len ),
33122			"start":          start,
33123			"end":            settings.fnDisplayEnd(),
33124			"length":         len,
33125			"recordsTotal":   settings.fnRecordsTotal(),
33126			"recordsDisplay": visRecords,
33127			"serverSide":     _fnDataSource( settings ) === 'ssp'
33128		};
33129	} );
33130
33131
33132	/**
33133	 * Get the current page length.
33134	 *
33135	 * @return {integer} Current page length. Note `-1` indicates that all records
33136	 *   are to be shown.
33137	 *//**
33138	 * Set the current page length.
33139	 *
33140	 * @param {integer} Page length to set. Use `-1` to show all records.
33141	 * @returns {DataTables.Api} this
33142	 */
33143	_api_register( 'page.len()', function ( len ) {
33144		// Note that we can't call this function 'length()' because `length`
33145		// is a Javascript property of functions which defines how many arguments
33146		// the function expects.
33147		if ( len === undefined ) {
33148			return this.context.length !== 0 ?
33149				this.context[0]._iDisplayLength :
33150				undefined;
33151		}
33152
33153		// else, set the page length
33154		return this.iterator( 'table', function ( settings ) {
33155			_fnLengthChange( settings, len );
33156		} );
33157	} );
33158
33159
33160
33161	var __reload = function ( settings, holdPosition, callback ) {
33162		// Use the draw event to trigger a callback
33163		if ( callback ) {
33164			var api = new _Api( settings );
33165
33166			api.one( 'draw', function () {
33167				callback( api.ajax.json() );
33168			} );
33169		}
33170
33171		if ( _fnDataSource( settings ) == 'ssp' ) {
33172			_fnReDraw( settings, holdPosition );
33173		}
33174		else {
33175			_fnProcessingDisplay( settings, true );
33176
33177			// Cancel an existing request
33178			var xhr = settings.jqXHR;
33179			if ( xhr && xhr.readyState !== 4 ) {
33180				xhr.abort();
33181			}
33182
33183			// Trigger xhr
33184			_fnBuildAjax( settings, [], function( json ) {
33185				_fnClearTable( settings );
33186
33187				var data = _fnAjaxDataSrc( settings, json );
33188				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
33189					_fnAddData( settings, data[i] );
33190				}
33191
33192				_fnReDraw( settings, holdPosition );
33193				_fnProcessingDisplay( settings, false );
33194			} );
33195		}
33196	};
33197
33198
33199	/**
33200	 * Get the JSON response from the last Ajax request that DataTables made to the
33201	 * server. Note that this returns the JSON from the first table in the current
33202	 * context.
33203	 *
33204	 * @return {object} JSON received from the server.
33205	 */
33206	_api_register( 'ajax.json()', function () {
33207		var ctx = this.context;
33208
33209		if ( ctx.length > 0 ) {
33210			return ctx[0].json;
33211		}
33212
33213		// else return undefined;
33214	} );
33215
33216
33217	/**
33218	 * Get the data submitted in the last Ajax request
33219	 */
33220	_api_register( 'ajax.params()', function () {
33221		var ctx = this.context;
33222
33223		if ( ctx.length > 0 ) {
33224			return ctx[0].oAjaxData;
33225		}
33226
33227		// else return undefined;
33228	} );
33229
33230
33231	/**
33232	 * Reload tables from the Ajax data source. Note that this function will
33233	 * automatically re-draw the table when the remote data has been loaded.
33234	 *
33235	 * @param {boolean} [reset=true] Reset (default) or hold the current paging
33236	 *   position. A full re-sort and re-filter is performed when this method is
33237	 *   called, which is why the pagination reset is the default action.
33238	 * @returns {DataTables.Api} this
33239	 */
33240	_api_register( 'ajax.reload()', function ( callback, resetPaging ) {
33241		return this.iterator( 'table', function (settings) {
33242			__reload( settings, resetPaging===false, callback );
33243		} );
33244	} );
33245
33246
33247	/**
33248	 * Get the current Ajax URL. Note that this returns the URL from the first
33249	 * table in the current context.
33250	 *
33251	 * @return {string} Current Ajax source URL
33252	 *//**
33253	 * Set the Ajax URL. Note that this will set the URL for all tables in the
33254	 * current context.
33255	 *
33256	 * @param {string} url URL to set.
33257	 * @returns {DataTables.Api} this
33258	 */
33259	_api_register( 'ajax.url()', function ( url ) {
33260		var ctx = this.context;
33261
33262		if ( url === undefined ) {
33263			// get
33264			if ( ctx.length === 0 ) {
33265				return undefined;
33266			}
33267			ctx = ctx[0];
33268
33269			return ctx.ajax ?
33270				$.isPlainObject( ctx.ajax ) ?
33271					ctx.ajax.url :
33272					ctx.ajax :
33273				ctx.sAjaxSource;
33274		}
33275
33276		// set
33277		return this.iterator( 'table', function ( settings ) {
33278			if ( $.isPlainObject( settings.ajax ) ) {
33279				settings.ajax.url = url;
33280			}
33281			else {
33282				settings.ajax = url;
33283			}
33284			// No need to consider sAjaxSource here since DataTables gives priority
33285			// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
33286			// value of `sAjaxSource` redundant.
33287		} );
33288	} );
33289
33290
33291	/**
33292	 * Load data from the newly set Ajax URL. Note that this method is only
33293	 * available when `ajax.url()` is used to set a URL. Additionally, this method
33294	 * has the same effect as calling `ajax.reload()` but is provided for
33295	 * convenience when setting a new URL. Like `ajax.reload()` it will
33296	 * automatically redraw the table once the remote data has been loaded.
33297	 *
33298	 * @returns {DataTables.Api} this
33299	 */
33300	_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
33301		// Same as a reload, but makes sense to present it for easy access after a
33302		// url change
33303		return this.iterator( 'table', function ( ctx ) {
33304			__reload( ctx, resetPaging===false, callback );
33305		} );
33306	} );
33307
33308
33309
33310
33311	var _selector_run = function ( type, selector, selectFn, settings, opts )
33312	{
33313		var
33314			out = [], res,
33315			a, i, ien, j, jen,
33316			selectorType = typeof selector;
33317
33318		// Can't just check for isArray here, as an API or jQuery instance might be
33319		// given with their array like look
33320		if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
33321			selector = [ selector ];
33322		}
33323
33324		for ( i=0, ien=selector.length ; i<ien ; i++ ) {
33325			a = selector[i] && selector[i].split ?
33326				selector[i].split(',') :
33327				[ selector[i] ];
33328
33329			for ( j=0, jen=a.length ; j<jen ; j++ ) {
33330				res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
33331
33332				if ( res && res.length ) {
33333					out = out.concat( res );
33334				}
33335			}
33336		}
33337
33338		// selector extensions
33339		var ext = _ext.selector[ type ];
33340		if ( ext.length ) {
33341			for ( i=0, ien=ext.length ; i<ien ; i++ ) {
33342				out = ext[i]( settings, opts, out );
33343			}
33344		}
33345
33346		return _unique( out );
33347	};
33348
33349
33350	var _selector_opts = function ( opts )
33351	{
33352		if ( ! opts ) {
33353			opts = {};
33354		}
33355
33356		// Backwards compatibility for 1.9- which used the terminology filter rather
33357		// than search
33358		if ( opts.filter && opts.search === undefined ) {
33359			opts.search = opts.filter;
33360		}
33361
33362		return $.extend( {
33363			search: 'none',
33364			order: 'current',
33365			page: 'all'
33366		}, opts );
33367	};
33368
33369
33370	var _selector_first = function ( inst )
33371	{
33372		// Reduce the API instance to the first item found
33373		for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
33374			if ( inst[i].length > 0 ) {
33375				// Assign the first element to the first item in the instance
33376				// and truncate the instance and context
33377				inst[0] = inst[i];
33378				inst[0].length = 1;
33379				inst.length = 1;
33380				inst.context = [ inst.context[i] ];
33381
33382				return inst;
33383			}
33384		}
33385
33386		// Not found - return an empty instance
33387		inst.length = 0;
33388		return inst;
33389	};
33390
33391
33392	var _selector_row_indexes = function ( settings, opts )
33393	{
33394		var
33395			i, ien, tmp, a=[],
33396			displayFiltered = settings.aiDisplay,
33397			displayMaster = settings.aiDisplayMaster;
33398
33399		var
33400			search = opts.search,  // none, applied, removed
33401			order  = opts.order,   // applied, current, index (original - compatibility with 1.9)
33402			page   = opts.page;    // all, current
33403
33404		if ( _fnDataSource( settings ) == 'ssp' ) {
33405			// In server-side processing mode, most options are irrelevant since
33406			// rows not shown don't exist and the index order is the applied order
33407			// Removed is a special case - for consistency just return an empty
33408			// array
33409			return search === 'removed' ?
33410				[] :
33411				_range( 0, displayMaster.length );
33412		}
33413		else if ( page == 'current' ) {
33414			// Current page implies that order=current and fitler=applied, since it is
33415			// fairly senseless otherwise, regardless of what order and search actually
33416			// are
33417			for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
33418				a.push( displayFiltered[i] );
33419			}
33420		}
33421		else if ( order == 'current' || order == 'applied' ) {
33422			a = search == 'none' ?
33423				displayMaster.slice() :                      // no search
33424				search == 'applied' ?
33425					displayFiltered.slice() :                // applied search
33426					$.map( displayMaster, function (el, i) { // removed search
33427						return $.inArray( el, displayFiltered ) === -1 ? el : null;
33428					} );
33429		}
33430		else if ( order == 'index' || order == 'original' ) {
33431			for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
33432				if ( search == 'none' ) {
33433					a.push( i );
33434				}
33435				else { // applied | removed
33436					tmp = $.inArray( i, displayFiltered );
33437
33438					if ((tmp === -1 && search == 'removed') ||
33439						(tmp >= 0   && search == 'applied') )
33440					{
33441						a.push( i );
33442					}
33443				}
33444			}
33445		}
33446
33447		return a;
33448	};
33449
33450
33451	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
33452	 * Rows
33453	 *
33454	 * {}          - no selector - use all available rows
33455	 * {integer}   - row aoData index
33456	 * {node}      - TR node
33457	 * {string}    - jQuery selector to apply to the TR elements
33458	 * {array}     - jQuery array of nodes, or simply an array of TR nodes
33459	 *
33460	 */
33461
33462
33463	var __row_selector = function ( settings, selector, opts )
33464	{
33465		var run = function ( sel ) {
33466			var selInt = _intVal( sel );
33467			var i, ien;
33468
33469			// Short cut - selector is a number and no options provided (default is
33470			// all records, so no need to check if the index is in there, since it
33471			// must be - dev error if the index doesn't exist).
33472			if ( selInt !== null && ! opts ) {
33473				return [ selInt ];
33474			}
33475
33476			var rows = _selector_row_indexes( settings, opts );
33477
33478			if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
33479				// Selector - integer
33480				return [ selInt ];
33481			}
33482			else if ( ! sel ) {
33483				// Selector - none
33484				return rows;
33485			}
33486
33487			// Selector - function
33488			if ( typeof sel === 'function' ) {
33489				return $.map( rows, function (idx) {
33490					var row = settings.aoData[ idx ];
33491					return sel( idx, row._aData, row.nTr ) ? idx : null;
33492				} );
33493			}
33494
33495			// Get nodes in the order from the `rows` array with null values removed
33496			var nodes = _removeEmpty(
33497				_pluck_order( settings.aoData, rows, 'nTr' )
33498			);
33499
33500			// Selector - node
33501			if ( sel.nodeName ) {
33502				if ( sel._DT_RowIndex !== undefined ) {
33503					return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup
33504				}
33505				else if ( sel._DT_CellIndex ) {
33506					return [ sel._DT_CellIndex.row ];
33507				}
33508				else {
33509					var host = $(sel).closest('*[data-dt-row]');
33510					return host.length ?
33511						[ host.data('dt-row') ] :
33512						[];
33513				}
33514			}
33515
33516			// ID selector. Want to always be able to select rows by id, regardless
33517			// of if the tr element has been created or not, so can't rely upon
33518			// jQuery here - hence a custom implementation. This does not match
33519			// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
33520			// but to select it using a CSS selector engine (like Sizzle or
33521			// querySelect) it would need to need to be escaped for some characters.
33522			// DataTables simplifies this for row selectors since you can select
33523			// only a row. A # indicates an id any anything that follows is the id -
33524			// unescaped.
33525			if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
33526				// get row index from id
33527				var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
33528				if ( rowObj !== undefined ) {
33529					return [ rowObj.idx ];
33530				}
33531
33532				// need to fall through to jQuery in case there is DOM id that
33533				// matches
33534			}
33535
33536			// Selector - jQuery selector string, array of nodes or jQuery object/
33537			// As jQuery's .filter() allows jQuery objects to be passed in filter,
33538			// it also allows arrays, so this will cope with all three options
33539			return $(nodes)
33540				.filter( sel )
33541				.map( function () {
33542					return this._DT_RowIndex;
33543				} )
33544				.toArray();
33545		};
33546
33547		return _selector_run( 'row', selector, run, settings, opts );
33548	};
33549
33550
33551	_api_register( 'rows()', function ( selector, opts ) {
33552		// argument shifting
33553		if ( selector === undefined ) {
33554			selector = '';
33555		}
33556		else if ( $.isPlainObject( selector ) ) {
33557			opts = selector;
33558			selector = '';
33559		}
33560
33561		opts = _selector_opts( opts );
33562
33563		var inst = this.iterator( 'table', function ( settings ) {
33564			return __row_selector( settings, selector, opts );
33565		}, 1 );
33566
33567		// Want argument shifting here and in __row_selector?
33568		inst.selector.rows = selector;
33569		inst.selector.opts = opts;
33570
33571		return inst;
33572	} );
33573
33574	_api_register( 'rows().nodes()', function () {
33575		return this.iterator( 'row', function ( settings, row ) {
33576			return settings.aoData[ row ].nTr || undefined;
33577		}, 1 );
33578	} );
33579
33580	_api_register( 'rows().data()', function () {
33581		return this.iterator( true, 'rows', function ( settings, rows ) {
33582			return _pluck_order( settings.aoData, rows, '_aData' );
33583		}, 1 );
33584	} );
33585
33586	_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
33587		return this.iterator( 'row', function ( settings, row ) {
33588			var r = settings.aoData[ row ];
33589			return type === 'search' ? r._aFilterData : r._aSortData;
33590		}, 1 );
33591	} );
33592
33593	_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
33594		return this.iterator( 'row', function ( settings, row ) {
33595			_fnInvalidate( settings, row, src );
33596		} );
33597	} );
33598
33599	_api_registerPlural( 'rows().indexes()', 'row().index()', function () {
33600		return this.iterator( 'row', function ( settings, row ) {
33601			return row;
33602		}, 1 );
33603	} );
33604
33605	_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
33606		var a = [];
33607		var context = this.context;
33608
33609		// `iterator` will drop undefined values, but in this case we want them
33610		for ( var i=0, ien=context.length ; i<ien ; i++ ) {
33611			for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
33612				var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
33613				a.push( (hash === true ? '#' : '' )+ id );
33614			}
33615		}
33616
33617		return new _Api( context, a );
33618	} );
33619
33620	_api_registerPlural( 'rows().remove()', 'row().remove()', function () {
33621		var that = this;
33622
33623		this.iterator( 'row', function ( settings, row, thatIdx ) {
33624			var data = settings.aoData;
33625			var rowData = data[ row ];
33626			var i, ien, j, jen;
33627			var loopRow, loopCells;
33628
33629			data.splice( row, 1 );
33630
33631			// Update the cached indexes
33632			for ( i=0, ien=data.length ; i<ien ; i++ ) {
33633				loopRow = data[i];
33634				loopCells = loopRow.anCells;
33635
33636				// Rows
33637				if ( loopRow.nTr !== null ) {
33638					loopRow.nTr._DT_RowIndex = i;
33639				}
33640
33641				// Cells
33642				if ( loopCells !== null ) {
33643					for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
33644						loopCells[j]._DT_CellIndex.row = i;
33645					}
33646				}
33647			}
33648
33649			// Delete from the display arrays
33650			_fnDeleteIndex( settings.aiDisplayMaster, row );
33651			_fnDeleteIndex( settings.aiDisplay, row );
33652			_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
33653
33654			// Check for an 'overflow' they case for displaying the table
33655			_fnLengthOverflow( settings );
33656
33657			// Remove the row's ID reference if there is one
33658			var id = settings.rowIdFn( rowData._aData );
33659			if ( id !== undefined ) {
33660				delete settings.aIds[ id ];
33661			}
33662		} );
33663
33664		this.iterator( 'table', function ( settings ) {
33665			for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
33666				settings.aoData[i].idx = i;
33667			}
33668		} );
33669
33670		return this;
33671	} );
33672
33673
33674	_api_register( 'rows.add()', function ( rows ) {
33675		var newRows = this.iterator( 'table', function ( settings ) {
33676			var row, i, ien;
33677			var out = [];
33678
33679			for ( i=0, ien=rows.length ; i<ien ; i++ ) {
33680				row = rows[i];
33681
33682				if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
33683					out.push( _fnAddTr( settings, row )[0] );
33684				}
33685				else {
33686					out.push( _fnAddData( settings, row ) );
33687				}
33688			}
33689
33690			return out;
33691		}, 1 );
33692
33693		// Return an Api.rows() extended instance, so rows().nodes() etc can be used
33694		var modRows = this.rows( -1 );
33695		modRows.pop();
33696		$.merge( modRows, newRows );
33697
33698		return modRows;
33699	} );
33700
33701
33702
33703
33704
33705	/**
33706	 *
33707	 */
33708	_api_register( 'row()', function ( selector, opts ) {
33709		return _selector_first( this.rows( selector, opts ) );
33710	} );
33711
33712
33713	_api_register( 'row().data()', function ( data ) {
33714		var ctx = this.context;
33715
33716		if ( data === undefined ) {
33717			// Get
33718			return ctx.length && this.length ?
33719				ctx[0].aoData[ this[0] ]._aData :
33720				undefined;
33721		}
33722
33723		// Set
33724		ctx[0].aoData[ this[0] ]._aData = data;
33725
33726		// Automatically invalidate
33727		_fnInvalidate( ctx[0], this[0], 'data' );
33728
33729		return this;
33730	} );
33731
33732
33733	_api_register( 'row().node()', function () {
33734		var ctx = this.context;
33735
33736		return ctx.length && this.length ?
33737			ctx[0].aoData[ this[0] ].nTr || null :
33738			null;
33739	} );
33740
33741
33742	_api_register( 'row.add()', function ( row ) {
33743		// Allow a jQuery object to be passed in - only a single row is added from
33744		// it though - the first element in the set
33745		if ( row instanceof $ && row.length ) {
33746			row = row[0];
33747		}
33748
33749		var rows = this.iterator( 'table', function ( settings ) {
33750			if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
33751				return _fnAddTr( settings, row )[0];
33752			}
33753			return _fnAddData( settings, row );
33754		} );
33755
33756		// Return an Api.rows() extended instance, with the newly added row selected
33757		return this.row( rows[0] );
33758	} );
33759
33760
33761
33762	var __details_add = function ( ctx, row, data, klass )
33763	{
33764		// Convert to array of TR elements
33765		var rows = [];
33766		var addRow = function ( r, k ) {
33767			// Recursion to allow for arrays of jQuery objects
33768			if ( $.isArray( r ) || r instanceof $ ) {
33769				for ( var i=0, ien=r.length ; i<ien ; i++ ) {
33770					addRow( r[i], k );
33771				}
33772				return;
33773			}
33774
33775			// If we get a TR element, then just add it directly - up to the dev
33776			// to add the correct number of columns etc
33777			if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
33778				rows.push( r );
33779			}
33780			else {
33781				// Otherwise create a row with a wrapper
33782				var created = $('<tr><td/></tr>').addClass( k );
33783				$('td', created)
33784					.addClass( k )
33785					.html( r )
33786					[0].colSpan = _fnVisbleColumns( ctx );
33787
33788				rows.push( created[0] );
33789			}
33790		};
33791
33792		addRow( data, klass );
33793
33794		if ( row._details ) {
33795			row._details.remove();
33796		}
33797
33798		row._details = $(rows);
33799
33800		// If the children were already shown, that state should be retained
33801		if ( row._detailsShow ) {
33802			row._details.insertAfter( row.nTr );
33803		}
33804	};
33805
33806
33807	var __details_remove = function ( api, idx )
33808	{
33809		var ctx = api.context;
33810
33811		if ( ctx.length ) {
33812			var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
33813
33814			if ( row && row._details ) {
33815				row._details.remove();
33816
33817				row._detailsShow = undefined;
33818				row._details = undefined;
33819			}
33820		}
33821	};
33822
33823
33824	var __details_display = function ( api, show ) {
33825		var ctx = api.context;
33826
33827		if ( ctx.length && api.length ) {
33828			var row = ctx[0].aoData[ api[0] ];
33829
33830			if ( row._details ) {
33831				row._detailsShow = show;
33832
33833				if ( show ) {
33834					row._details.insertAfter( row.nTr );
33835				}
33836				else {
33837					row._details.detach();
33838				}
33839
33840				__details_events( ctx[0] );
33841			}
33842		}
33843	};
33844
33845
33846	var __details_events = function ( settings )
33847	{
33848		var api = new _Api( settings );
33849		var namespace = '.dt.DT_details';
33850		var drawEvent = 'draw'+namespace;
33851		var colvisEvent = 'column-visibility'+namespace;
33852		var destroyEvent = 'destroy'+namespace;
33853		var data = settings.aoData;
33854
33855		api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
33856
33857		if ( _pluck( data, '_details' ).length > 0 ) {
33858			// On each draw, insert the required elements into the document
33859			api.on( drawEvent, function ( e, ctx ) {
33860				if ( settings !== ctx ) {
33861					return;
33862				}
33863
33864				api.rows( {page:'current'} ).eq(0).each( function (idx) {
33865					// Internal data grab
33866					var row = data[ idx ];
33867
33868					if ( row._detailsShow ) {
33869						row._details.insertAfter( row.nTr );
33870					}
33871				} );
33872			} );
33873
33874			// Column visibility change - update the colspan
33875			api.on( colvisEvent, function ( e, ctx, idx, vis ) {
33876				if ( settings !== ctx ) {
33877					return;
33878				}
33879
33880				// Update the colspan for the details rows (note, only if it already has
33881				// a colspan)
33882				var row, visible = _fnVisbleColumns( ctx );
33883
33884				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
33885					row = data[i];
33886
33887					if ( row._details ) {
33888						row._details.children('td[colspan]').attr('colspan', visible );
33889					}
33890				}
33891			} );
33892
33893			// Table destroyed - nuke any child rows
33894			api.on( destroyEvent, function ( e, ctx ) {
33895				if ( settings !== ctx ) {
33896					return;
33897				}
33898
33899				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
33900					if ( data[i]._details ) {
33901						__details_remove( api, i );
33902					}
33903				}
33904			} );
33905		}
33906	};
33907
33908	// Strings for the method names to help minification
33909	var _emp = '';
33910	var _child_obj = _emp+'row().child';
33911	var _child_mth = _child_obj+'()';
33912
33913	// data can be:
33914	//  tr
33915	//  string
33916	//  jQuery or array of any of the above
33917	_api_register( _child_mth, function ( data, klass ) {
33918		var ctx = this.context;
33919
33920		if ( data === undefined ) {
33921			// get
33922			return ctx.length && this.length ?
33923				ctx[0].aoData[ this[0] ]._details :
33924				undefined;
33925		}
33926		else if ( data === true ) {
33927			// show
33928			this.child.show();
33929		}
33930		else if ( data === false ) {
33931			// remove
33932			__details_remove( this );
33933		}
33934		else if ( ctx.length && this.length ) {
33935			// set
33936			__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
33937		}
33938
33939		return this;
33940	} );
33941
33942
33943	_api_register( [
33944		_child_obj+'.show()',
33945		_child_mth+'.show()' // only when `child()` was called with parameters (without
33946	], function ( show ) {   // it returns an object and this method is not executed)
33947		__details_display( this, true );
33948		return this;
33949	} );
33950
33951
33952	_api_register( [
33953		_child_obj+'.hide()',
33954		_child_mth+'.hide()' // only when `child()` was called with parameters (without
33955	], function () {         // it returns an object and this method is not executed)
33956		__details_display( this, false );
33957		return this;
33958	} );
33959
33960
33961	_api_register( [
33962		_child_obj+'.remove()',
33963		_child_mth+'.remove()' // only when `child()` was called with parameters (without
33964	], function () {           // it returns an object and this method is not executed)
33965		__details_remove( this );
33966		return this;
33967	} );
33968
33969
33970	_api_register( _child_obj+'.isShown()', function () {
33971		var ctx = this.context;
33972
33973		if ( ctx.length && this.length ) {
33974			// _detailsShown as false or undefined will fall through to return false
33975			return ctx[0].aoData[ this[0] ]._detailsShow || false;
33976		}
33977		return false;
33978	} );
33979
33980
33981
33982	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
33983	 * Columns
33984	 *
33985	 * {integer}           - column index (>=0 count from left, <0 count from right)
33986	 * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
33987	 * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
33988	 * "{string}:name"     - column name
33989	 * "{string}"          - jQuery selector on column header nodes
33990	 *
33991	 */
33992
33993	// can be an array of these items, comma separated list, or an array of comma
33994	// separated lists
33995
33996	var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
33997
33998
33999	// r1 and r2 are redundant - but it means that the parameters match for the
34000	// iterator callback in columns().data()
34001	var __columnData = function ( settings, column, r1, r2, rows ) {
34002		var a = [];
34003		for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
34004			a.push( _fnGetCellData( settings, rows[row], column ) );
34005		}
34006		return a;
34007	};
34008
34009
34010	var __column_selector = function ( settings, selector, opts )
34011	{
34012		var
34013			columns = settings.aoColumns,
34014			names = _pluck( columns, 'sName' ),
34015			nodes = _pluck( columns, 'nTh' );
34016
34017		var run = function ( s ) {
34018			var selInt = _intVal( s );
34019
34020			// Selector - all
34021			if ( s === '' ) {
34022				return _range( columns.length );
34023			}
34024
34025			// Selector - index
34026			if ( selInt !== null ) {
34027				return [ selInt >= 0 ?
34028					selInt : // Count from left
34029					columns.length + selInt // Count from right (+ because its a negative value)
34030				];
34031			}
34032
34033			// Selector = function
34034			if ( typeof s === 'function' ) {
34035				var rows = _selector_row_indexes( settings, opts );
34036
34037				return $.map( columns, function (col, idx) {
34038					return s(
34039						idx,
34040						__columnData( settings, idx, 0, 0, rows ),
34041						nodes[ idx ]
34042					) ? idx : null;
34043				} );
34044			}
34045
34046			// jQuery or string selector
34047			var match = typeof s === 'string' ?
34048				s.match( __re_column_selector ) :
34049				'';
34050
34051			if ( match ) {
34052				switch( match[2] ) {
34053					case 'visIdx':
34054					case 'visible':
34055						var idx = parseInt( match[1], 10 );
34056						// Visible index given, convert to column index
34057						if ( idx < 0 ) {
34058							// Counting from the right
34059							var visColumns = $.map( columns, function (col,i) {
34060								return col.bVisible ? i : null;
34061							} );
34062							return [ visColumns[ visColumns.length + idx ] ];
34063						}
34064						// Counting from the left
34065						return [ _fnVisibleToColumnIndex( settings, idx ) ];
34066
34067					case 'name':
34068						// match by name. `names` is column index complete and in order
34069						return $.map( names, function (name, i) {
34070							return name === match[1] ? i : null;
34071						} );
34072
34073					default:
34074						return [];
34075				}
34076			}
34077
34078			// Cell in the table body
34079			if ( s.nodeName && s._DT_CellIndex ) {
34080				return [ s._DT_CellIndex.column ];
34081			}
34082
34083			// jQuery selector on the TH elements for the columns
34084			var jqResult = $( nodes )
34085				.filter( s )
34086				.map( function () {
34087					return $.inArray( this, nodes ); // `nodes` is column index complete and in order
34088				} )
34089				.toArray();
34090
34091			if ( jqResult.length || ! s.nodeName ) {
34092				return jqResult;
34093			}
34094
34095			// Otherwise a node which might have a `dt-column` data attribute, or be
34096			// a child or such an element
34097			var host = $(s).closest('*[data-dt-column]');
34098			return host.length ?
34099				[ host.data('dt-column') ] :
34100				[];
34101		};
34102
34103		return _selector_run( 'column', selector, run, settings, opts );
34104	};
34105
34106
34107	var __setColumnVis = function ( settings, column, vis ) {
34108		var
34109			cols = settings.aoColumns,
34110			col  = cols[ column ],
34111			data = settings.aoData,
34112			row, cells, i, ien, tr;
34113
34114		// Get
34115		if ( vis === undefined ) {
34116			return col.bVisible;
34117		}
34118
34119		// Set
34120		// No change
34121		if ( col.bVisible === vis ) {
34122			return;
34123		}
34124
34125		if ( vis ) {
34126			// Insert column
34127			// Need to decide if we should use appendChild or insertBefore
34128			var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
34129
34130			for ( i=0, ien=data.length ; i<ien ; i++ ) {
34131				tr = data[i].nTr;
34132				cells = data[i].anCells;
34133
34134				if ( tr ) {
34135					// insertBefore can act like appendChild if 2nd arg is null
34136					tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
34137				}
34138			}
34139		}
34140		else {
34141			// Remove column
34142			$( _pluck( settings.aoData, 'anCells', column ) ).detach();
34143		}
34144
34145		// Common actions
34146		col.bVisible = vis;
34147		_fnDrawHead( settings, settings.aoHeader );
34148		_fnDrawHead( settings, settings.aoFooter );
34149
34150		_fnSaveState( settings );
34151	};
34152
34153
34154	_api_register( 'columns()', function ( selector, opts ) {
34155		// argument shifting
34156		if ( selector === undefined ) {
34157			selector = '';
34158		}
34159		else if ( $.isPlainObject( selector ) ) {
34160			opts = selector;
34161			selector = '';
34162		}
34163
34164		opts = _selector_opts( opts );
34165
34166		var inst = this.iterator( 'table', function ( settings ) {
34167			return __column_selector( settings, selector, opts );
34168		}, 1 );
34169
34170		// Want argument shifting here and in _row_selector?
34171		inst.selector.cols = selector;
34172		inst.selector.opts = opts;
34173
34174		return inst;
34175	} );
34176
34177	_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
34178		return this.iterator( 'column', function ( settings, column ) {
34179			return settings.aoColumns[column].nTh;
34180		}, 1 );
34181	} );
34182
34183	_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
34184		return this.iterator( 'column', function ( settings, column ) {
34185			return settings.aoColumns[column].nTf;
34186		}, 1 );
34187	} );
34188
34189	_api_registerPlural( 'columns().data()', 'column().data()', function () {
34190		return this.iterator( 'column-rows', __columnData, 1 );
34191	} );
34192
34193	_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
34194		return this.iterator( 'column', function ( settings, column ) {
34195			return settings.aoColumns[column].mData;
34196		}, 1 );
34197	} );
34198
34199	_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
34200		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
34201			return _pluck_order( settings.aoData, rows,
34202				type === 'search' ? '_aFilterData' : '_aSortData', column
34203			);
34204		}, 1 );
34205	} );
34206
34207	_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
34208		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
34209			return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
34210		}, 1 );
34211	} );
34212
34213	_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
34214		var ret = this.iterator( 'column', function ( settings, column ) {
34215			if ( vis === undefined ) {
34216				return settings.aoColumns[ column ].bVisible;
34217			} // else
34218			__setColumnVis( settings, column, vis );
34219		} );
34220
34221		// Group the column visibility changes
34222		if ( vis !== undefined ) {
34223			// Second loop once the first is done for events
34224			this.iterator( 'column', function ( settings, column ) {
34225				_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
34226			} );
34227
34228			if ( calc === undefined || calc ) {
34229				this.columns.adjust();
34230			}
34231		}
34232
34233		return ret;
34234	} );
34235
34236	_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
34237		return this.iterator( 'column', function ( settings, column ) {
34238			return type === 'visible' ?
34239				_fnColumnIndexToVisible( settings, column ) :
34240				column;
34241		}, 1 );
34242	} );
34243
34244	_api_register( 'columns.adjust()', function () {
34245		return this.iterator( 'table', function ( settings ) {
34246			_fnAdjustColumnSizing( settings );
34247		}, 1 );
34248	} );
34249
34250	_api_register( 'column.index()', function ( type, idx ) {
34251		if ( this.context.length !== 0 ) {
34252			var ctx = this.context[0];
34253
34254			if ( type === 'fromVisible' || type === 'toData' ) {
34255				return _fnVisibleToColumnIndex( ctx, idx );
34256			}
34257			else if ( type === 'fromData' || type === 'toVisible' ) {
34258				return _fnColumnIndexToVisible( ctx, idx );
34259			}
34260		}
34261	} );
34262
34263	_api_register( 'column()', function ( selector, opts ) {
34264		return _selector_first( this.columns( selector, opts ) );
34265	} );
34266
34267
34268
34269	var __cell_selector = function ( settings, selector, opts )
34270	{
34271		var data = settings.aoData;
34272		var rows = _selector_row_indexes( settings, opts );
34273		var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
34274		var allCells = $( [].concat.apply([], cells) );
34275		var row;
34276		var columns = settings.aoColumns.length;
34277		var a, i, ien, j, o, host;
34278
34279		var run = function ( s ) {
34280			var fnSelector = typeof s === 'function';
34281
34282			if ( s === null || s === undefined || fnSelector ) {
34283				// All cells and function selectors
34284				a = [];
34285
34286				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
34287					row = rows[i];
34288
34289					for ( j=0 ; j<columns ; j++ ) {
34290						o = {
34291							row: row,
34292							column: j
34293						};
34294
34295						if ( fnSelector ) {
34296							// Selector - function
34297							host = data[ row ];
34298
34299							if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
34300								a.push( o );
34301							}
34302						}
34303						else {
34304							// Selector - all
34305							a.push( o );
34306						}
34307					}
34308				}
34309
34310				return a;
34311			}
34312
34313			// Selector - index
34314			if ( $.isPlainObject( s ) ) {
34315				return [s];
34316			}
34317
34318			// Selector - jQuery filtered cells
34319			var jqResult = allCells
34320				.filter( s )
34321				.map( function (i, el) {
34322					return { // use a new object, in case someone changes the values
34323						row:    el._DT_CellIndex.row,
34324						column: el._DT_CellIndex.column
34325					};
34326				} )
34327				.toArray();
34328
34329			if ( jqResult.length || ! s.nodeName ) {
34330				return jqResult;
34331			}
34332
34333			// Otherwise the selector is a node, and there is one last option - the
34334			// element might be a child of an element which has dt-row and dt-column
34335			// data attributes
34336			host = $(s).closest('*[data-dt-row]');
34337			return host.length ?
34338				[ {
34339					row: host.data('dt-row'),
34340					column: host.data('dt-column')
34341				} ] :
34342				[];
34343		};
34344
34345		return _selector_run( 'cell', selector, run, settings, opts );
34346	};
34347
34348
34349
34350
34351	_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
34352		// Argument shifting
34353		if ( $.isPlainObject( rowSelector ) ) {
34354			// Indexes
34355			if ( rowSelector.row === undefined ) {
34356				// Selector options in first parameter
34357				opts = rowSelector;
34358				rowSelector = null;
34359			}
34360			else {
34361				// Cell index objects in first parameter
34362				opts = columnSelector;
34363				columnSelector = null;
34364			}
34365		}
34366		if ( $.isPlainObject( columnSelector ) ) {
34367			opts = columnSelector;
34368			columnSelector = null;
34369		}
34370
34371		// Cell selector
34372		if ( columnSelector === null || columnSelector === undefined ) {
34373			return this.iterator( 'table', function ( settings ) {
34374				return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
34375			} );
34376		}
34377
34378		// Row + column selector
34379		var columns = this.columns( columnSelector, opts );
34380		var rows = this.rows( rowSelector, opts );
34381		var a, i, ien, j, jen;
34382
34383		var cells = this.iterator( 'table', function ( settings, idx ) {
34384			a = [];
34385
34386			for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
34387				for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
34388					a.push( {
34389						row:    rows[idx][i],
34390						column: columns[idx][j]
34391					} );
34392				}
34393			}
34394
34395			return a;
34396		}, 1 );
34397
34398		$.extend( cells.selector, {
34399			cols: columnSelector,
34400			rows: rowSelector,
34401			opts: opts
34402		} );
34403
34404		return cells;
34405	} );
34406
34407
34408	_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
34409		return this.iterator( 'cell', function ( settings, row, column ) {
34410			var data = settings.aoData[ row ];
34411
34412			return data && data.anCells ?
34413				data.anCells[ column ] :
34414				undefined;
34415		}, 1 );
34416	} );
34417
34418
34419	_api_register( 'cells().data()', function () {
34420		return this.iterator( 'cell', function ( settings, row, column ) {
34421			return _fnGetCellData( settings, row, column );
34422		}, 1 );
34423	} );
34424
34425
34426	_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
34427		type = type === 'search' ? '_aFilterData' : '_aSortData';
34428
34429		return this.iterator( 'cell', function ( settings, row, column ) {
34430			return settings.aoData[ row ][ type ][ column ];
34431		}, 1 );
34432	} );
34433
34434
34435	_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
34436		return this.iterator( 'cell', function ( settings, row, column ) {
34437			return _fnGetCellData( settings, row, column, type );
34438		}, 1 );
34439	} );
34440
34441
34442	_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
34443		return this.iterator( 'cell', function ( settings, row, column ) {
34444			return {
34445				row: row,
34446				column: column,
34447				columnVisible: _fnColumnIndexToVisible( settings, column )
34448			};
34449		}, 1 );
34450	} );
34451
34452
34453	_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
34454		return this.iterator( 'cell', function ( settings, row, column ) {
34455			_fnInvalidate( settings, row, src, column );
34456		} );
34457	} );
34458
34459
34460
34461	_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
34462		return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
34463	} );
34464
34465
34466	_api_register( 'cell().data()', function ( data ) {
34467		var ctx = this.context;
34468		var cell = this[0];
34469
34470		if ( data === undefined ) {
34471			// Get
34472			return ctx.length && cell.length ?
34473				_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
34474				undefined;
34475		}
34476
34477		// Set
34478		_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
34479		_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
34480
34481		return this;
34482	} );
34483
34484
34485
34486	/**
34487	 * Get current ordering (sorting) that has been applied to the table.
34488	 *
34489	 * @returns {array} 2D array containing the sorting information for the first
34490	 *   table in the current context. Each element in the parent array represents
34491	 *   a column being sorted upon (i.e. multi-sorting with two columns would have
34492	 *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
34493	 *   the column index that the sorting condition applies to, the second is the
34494	 *   direction of the sort (`desc` or `asc`) and, optionally, the third is the
34495	 *   index of the sorting order from the `column.sorting` initialisation array.
34496	 *//**
34497	 * Set the ordering for the table.
34498	 *
34499	 * @param {integer} order Column index to sort upon.
34500	 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
34501	 * @returns {DataTables.Api} this
34502	 *//**
34503	 * Set the ordering for the table.
34504	 *
34505	 * @param {array} order 1D array of sorting information to be applied.
34506	 * @param {array} [...] Optional additional sorting conditions
34507	 * @returns {DataTables.Api} this
34508	 *//**
34509	 * Set the ordering for the table.
34510	 *
34511	 * @param {array} order 2D array of sorting information to be applied.
34512	 * @returns {DataTables.Api} this
34513	 */
34514	_api_register( 'order()', function ( order, dir ) {
34515		var ctx = this.context;
34516
34517		if ( order === undefined ) {
34518			// get
34519			return ctx.length !== 0 ?
34520				ctx[0].aaSorting :
34521				undefined;
34522		}
34523
34524		// set
34525		if ( typeof order === 'number' ) {
34526			// Simple column / direction passed in
34527			order = [ [ order, dir ] ];
34528		}
34529		else if ( order.length && ! $.isArray( order[0] ) ) {
34530			// Arguments passed in (list of 1D arrays)
34531			order = Array.prototype.slice.call( arguments );
34532		}
34533		// otherwise a 2D array was passed in
34534
34535		return this.iterator( 'table', function ( settings ) {
34536			settings.aaSorting = order.slice();
34537		} );
34538	} );
34539
34540
34541	/**
34542	 * Attach a sort listener to an element for a given column
34543	 *
34544	 * @param {node|jQuery|string} node Identifier for the element(s) to attach the
34545	 *   listener to. This can take the form of a single DOM node, a jQuery
34546	 *   collection of nodes or a jQuery selector which will identify the node(s).
34547	 * @param {integer} column the column that a click on this node will sort on
34548	 * @param {function} [callback] callback function when sort is run
34549	 * @returns {DataTables.Api} this
34550	 */
34551	_api_register( 'order.listener()', function ( node, column, callback ) {
34552		return this.iterator( 'table', function ( settings ) {
34553			_fnSortAttachListener( settings, node, column, callback );
34554		} );
34555	} );
34556
34557
34558	_api_register( 'order.fixed()', function ( set ) {
34559		if ( ! set ) {
34560			var ctx = this.context;
34561			var fixed = ctx.length ?
34562				ctx[0].aaSortingFixed :
34563				undefined;
34564
34565			return $.isArray( fixed ) ?
34566				{ pre: fixed } :
34567				fixed;
34568		}
34569
34570		return this.iterator( 'table', function ( settings ) {
34571			settings.aaSortingFixed = $.extend( true, {}, set );
34572		} );
34573	} );
34574
34575
34576	// Order by the selected column(s)
34577	_api_register( [
34578		'columns().order()',
34579		'column().order()'
34580	], function ( dir ) {
34581		var that = this;
34582
34583		return this.iterator( 'table', function ( settings, i ) {
34584			var sort = [];
34585
34586			$.each( that[i], function (j, col) {
34587				sort.push( [ col, dir ] );
34588			} );
34589
34590			settings.aaSorting = sort;
34591		} );
34592	} );
34593
34594
34595
34596	_api_register( 'search()', function ( input, regex, smart, caseInsen ) {
34597		var ctx = this.context;
34598
34599		if ( input === undefined ) {
34600			// get
34601			return ctx.length !== 0 ?
34602				ctx[0].oPreviousSearch.sSearch :
34603				undefined;
34604		}
34605
34606		// set
34607		return this.iterator( 'table', function ( settings ) {
34608			if ( ! settings.oFeatures.bFilter ) {
34609				return;
34610			}
34611
34612			_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
34613				"sSearch": input+"",
34614				"bRegex":  regex === null ? false : regex,
34615				"bSmart":  smart === null ? true  : smart,
34616				"bCaseInsensitive": caseInsen === null ? true : caseInsen
34617			} ), 1 );
34618		} );
34619	} );
34620
34621
34622	_api_registerPlural(
34623		'columns().search()',
34624		'column().search()',
34625		function ( input, regex, smart, caseInsen ) {
34626			return this.iterator( 'column', function ( settings, column ) {
34627				var preSearch = settings.aoPreSearchCols;
34628
34629				if ( input === undefined ) {
34630					// get
34631					return preSearch[ column ].sSearch;
34632				}
34633
34634				// set
34635				if ( ! settings.oFeatures.bFilter ) {
34636					return;
34637				}
34638
34639				$.extend( preSearch[ column ], {
34640					"sSearch": input+"",
34641					"bRegex":  regex === null ? false : regex,
34642					"bSmart":  smart === null ? true  : smart,
34643					"bCaseInsensitive": caseInsen === null ? true : caseInsen
34644				} );
34645
34646				_fnFilterComplete( settings, settings.oPreviousSearch, 1 );
34647			} );
34648		}
34649	);
34650
34651	/*
34652	 * State API methods
34653	 */
34654
34655	_api_register( 'state()', function () {
34656		return this.context.length ?
34657			this.context[0].oSavedState :
34658			null;
34659	} );
34660
34661
34662	_api_register( 'state.clear()', function () {
34663		return this.iterator( 'table', function ( settings ) {
34664			// Save an empty object
34665			settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
34666		} );
34667	} );
34668
34669
34670	_api_register( 'state.loaded()', function () {
34671		return this.context.length ?
34672			this.context[0].oLoadedState :
34673			null;
34674	} );
34675
34676
34677	_api_register( 'state.save()', function () {
34678		return this.iterator( 'table', function ( settings ) {
34679			_fnSaveState( settings );
34680		} );
34681	} );
34682
34683
34684
34685	/**
34686	 * Provide a common method for plug-ins to check the version of DataTables being
34687	 * used, in order to ensure compatibility.
34688	 *
34689	 *  @param {string} version Version string to check for, in the format "X.Y.Z".
34690	 *    Note that the formats "X" and "X.Y" are also acceptable.
34691	 *  @returns {boolean} true if this version of DataTables is greater or equal to
34692	 *    the required version, or false if this version of DataTales is not
34693	 *    suitable
34694	 *  @static
34695	 *  @dtopt API-Static
34696	 *
34697	 *  @example
34698	 *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
34699	 */
34700	DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
34701	{
34702		var aThis = DataTable.version.split('.');
34703		var aThat = version.split('.');
34704		var iThis, iThat;
34705
34706		for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
34707			iThis = parseInt( aThis[i], 10 ) || 0;
34708			iThat = parseInt( aThat[i], 10 ) || 0;
34709
34710			// Parts are the same, keep comparing
34711			if (iThis === iThat) {
34712				continue;
34713			}
34714
34715			// Parts are different, return immediately
34716			return iThis > iThat;
34717		}
34718
34719		return true;
34720	};
34721
34722
34723	/**
34724	 * Check if a `<table>` node is a DataTable table already or not.
34725	 *
34726	 *  @param {node|jquery|string} table Table node, jQuery object or jQuery
34727	 *      selector for the table to test. Note that if more than more than one
34728	 *      table is passed on, only the first will be checked
34729	 *  @returns {boolean} true the table given is a DataTable, or false otherwise
34730	 *  @static
34731	 *  @dtopt API-Static
34732	 *
34733	 *  @example
34734	 *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
34735	 *      $('#example').dataTable();
34736	 *    }
34737	 */
34738	DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
34739	{
34740		var t = $(table).get(0);
34741		var is = false;
34742
34743		$.each( DataTable.settings, function (i, o) {
34744			var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
34745			var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
34746
34747			if ( o.nTable === t || head === t || foot === t ) {
34748				is = true;
34749			}
34750		} );
34751
34752		return is;
34753	};
34754
34755
34756	/**
34757	 * Get all DataTable tables that have been initialised - optionally you can
34758	 * select to get only currently visible tables.
34759	 *
34760	 *  @param {boolean} [visible=false] Flag to indicate if you want all (default)
34761	 *    or visible tables only.
34762	 *  @returns {array} Array of `table` nodes (not DataTable instances) which are
34763	 *    DataTables
34764	 *  @static
34765	 *  @dtopt API-Static
34766	 *
34767	 *  @example
34768	 *    $.each( $.fn.dataTable.tables(true), function () {
34769	 *      $(table).DataTable().columns.adjust();
34770	 *    } );
34771	 */
34772	DataTable.tables = DataTable.fnTables = function ( visible )
34773	{
34774		var api = false;
34775
34776		if ( $.isPlainObject( visible ) ) {
34777			api = visible.api;
34778			visible = visible.visible;
34779		}
34780
34781		var a = $.map( DataTable.settings, function (o) {
34782			if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
34783				return o.nTable;
34784			}
34785		} );
34786
34787		return api ?
34788			new _Api( a ) :
34789			a;
34790	};
34791
34792
34793	/**
34794	 * Convert from camel case parameters to Hungarian notation. This is made public
34795	 * for the extensions to provide the same ability as DataTables core to accept
34796	 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
34797	 * parameters.
34798	 *
34799	 *  @param {object} src The model object which holds all parameters that can be
34800	 *    mapped.
34801	 *  @param {object} user The object to convert from camel case to Hungarian.
34802	 *  @param {boolean} force When set to `true`, properties which already have a
34803	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
34804	 *    won't be.
34805	 */
34806	DataTable.camelToHungarian = _fnCamelToHungarian;
34807
34808
34809
34810	/**
34811	 *
34812	 */
34813	_api_register( '$()', function ( selector, opts ) {
34814		var
34815			rows   = this.rows( opts ).nodes(), // Get all rows
34816			jqRows = $(rows);
34817
34818		return $( [].concat(
34819			jqRows.filter( selector ).toArray(),
34820			jqRows.find( selector ).toArray()
34821		) );
34822	} );
34823
34824
34825	// jQuery functions to operate on the tables
34826	$.each( [ 'on', 'one', 'off' ], function (i, key) {
34827		_api_register( key+'()', function ( /* event, handler */ ) {
34828			var args = Array.prototype.slice.call(arguments);
34829
34830			// Add the `dt` namespace automatically if it isn't already present
34831			if ( ! args[0].match(/\.dt\b/) ) {
34832				args[0] += '.dt';
34833			}
34834
34835			var inst = $( this.tables().nodes() );
34836			inst[key].apply( inst, args );
34837			return this;
34838		} );
34839	} );
34840
34841
34842	_api_register( 'clear()', function () {
34843		return this.iterator( 'table', function ( settings ) {
34844			_fnClearTable( settings );
34845		} );
34846	} );
34847
34848
34849	_api_register( 'settings()', function () {
34850		return new _Api( this.context, this.context );
34851	} );
34852
34853
34854	_api_register( 'init()', function () {
34855		var ctx = this.context;
34856		return ctx.length ? ctx[0].oInit : null;
34857	} );
34858
34859
34860	_api_register( 'data()', function () {
34861		return this.iterator( 'table', function ( settings ) {
34862			return _pluck( settings.aoData, '_aData' );
34863		} ).flatten();
34864	} );
34865
34866
34867	_api_register( 'destroy()', function ( remove ) {
34868		remove = remove || false;
34869
34870		return this.iterator( 'table', function ( settings ) {
34871			var orig      = settings.nTableWrapper.parentNode;
34872			var classes   = settings.oClasses;
34873			var table     = settings.nTable;
34874			var tbody     = settings.nTBody;
34875			var thead     = settings.nTHead;
34876			var tfoot     = settings.nTFoot;
34877			var jqTable   = $(table);
34878			var jqTbody   = $(tbody);
34879			var jqWrapper = $(settings.nTableWrapper);
34880			var rows      = $.map( settings.aoData, function (r) { return r.nTr; } );
34881			var i, ien;
34882
34883			// Flag to note that the table is currently being destroyed - no action
34884			// should be taken
34885			settings.bDestroying = true;
34886
34887			// Fire off the destroy callbacks for plug-ins etc
34888			_fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
34889
34890			// If not being removed from the document, make all columns visible
34891			if ( ! remove ) {
34892				new _Api( settings ).columns().visible( true );
34893			}
34894
34895			// Blitz all `DT` namespaced events (these are internal events, the
34896			// lowercase, `dt` events are user subscribed and they are responsible
34897			// for removing them
34898			jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
34899			$(window).unbind('.DT-'+settings.sInstance);
34900
34901			// When scrolling we had to break the table up - restore it
34902			if ( table != thead.parentNode ) {
34903				jqTable.children('thead').detach();
34904				jqTable.append( thead );
34905			}
34906
34907			if ( tfoot && table != tfoot.parentNode ) {
34908				jqTable.children('tfoot').detach();
34909				jqTable.append( tfoot );
34910			}
34911
34912			settings.aaSorting = [];
34913			settings.aaSortingFixed = [];
34914			_fnSortingClasses( settings );
34915
34916			$( rows ).removeClass( settings.asStripeClasses.join(' ') );
34917
34918			$('th, td', thead).removeClass( classes.sSortable+' '+
34919				classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
34920			);
34921
34922			if ( settings.bJUI ) {
34923				$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
34924				$('th, td', thead).each( function () {
34925					var wrapper = $('div.'+classes.sSortJUIWrapper, this);
34926					$(this).append( wrapper.contents() );
34927					wrapper.detach();
34928				} );
34929			}
34930
34931			// Add the TR elements back into the table in their original order
34932			jqTbody.children().detach();
34933			jqTbody.append( rows );
34934
34935			// Remove the DataTables generated nodes, events and classes
34936			var removedMethod = remove ? 'remove' : 'detach';
34937			jqTable[ removedMethod ]();
34938			jqWrapper[ removedMethod ]();
34939
34940			// If we need to reattach the table to the document
34941			if ( ! remove && orig ) {
34942				// insertBefore acts like appendChild if !arg[1]
34943				orig.insertBefore( table, settings.nTableReinsertBefore );
34944
34945				// Restore the width of the original table - was read from the style property,
34946				// so we can restore directly to that
34947				jqTable
34948					.css( 'width', settings.sDestroyWidth )
34949					.removeClass( classes.sTable );
34950
34951				// If the were originally stripe classes - then we add them back here.
34952				// Note this is not fool proof (for example if not all rows had stripe
34953				// classes - but it's a good effort without getting carried away
34954				ien = settings.asDestroyStripes.length;
34955
34956				if ( ien ) {
34957					jqTbody.children().each( function (i) {
34958						$(this).addClass( settings.asDestroyStripes[i % ien] );
34959					} );
34960				}
34961			}
34962
34963			/* Remove the settings object from the settings array */
34964			var idx = $.inArray( settings, DataTable.settings );
34965			if ( idx !== -1 ) {
34966				DataTable.settings.splice( idx, 1 );
34967			}
34968		} );
34969	} );
34970
34971
34972	// Add the `every()` method for rows, columns and cells in a compact form
34973	$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
34974		_api_register( type+'s().every()', function ( fn ) {
34975			var opts = this.selector.opts;
34976			var api = this;
34977
34978			return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
34979				// Rows and columns:
34980				//  arg1 - index
34981				//  arg2 - table counter
34982				//  arg3 - loop counter
34983				//  arg4 - undefined
34984				// Cells:
34985				//  arg1 - row index
34986				//  arg2 - column index
34987				//  arg3 - table counter
34988				//  arg4 - loop counter
34989				fn.call(
34990					api[ type ](
34991						arg1,
34992						type==='cell' ? arg2 : opts,
34993						type==='cell' ? opts : undefined
34994					),
34995					arg1, arg2, arg3, arg4
34996				);
34997			} );
34998		} );
34999	} );
35000
35001
35002	// i18n method for extensions to be able to use the language object from the
35003	// DataTable
35004	_api_register( 'i18n()', function ( token, def, plural ) {
35005		var ctx = this.context[0];
35006		var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
35007
35008		if ( resolved === undefined ) {
35009			resolved = def;
35010		}
35011
35012		if ( plural !== undefined && $.isPlainObject( resolved ) ) {
35013			resolved = resolved[ plural ] !== undefined ?
35014				resolved[ plural ] :
35015				resolved._;
35016		}
35017
35018		return resolved.replace( '%d', plural ); // nb: plural might be undefined,
35019	} );
35020	/**
35021	 * Version string for plug-ins to check compatibility. Allowed format is
35022	 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
35023	 * only for non-release builds. See http://semver.org/ for more information.
35024	 *  @member
35025	 *  @type string
35026	 *  @default Version number
35027	 */
35028	DataTable.version = "1.10.12";
35029
35030	/**
35031	 * Private data store, containing all of the settings objects that are
35032	 * created for the tables on a given page.
35033	 *
35034	 * Note that the `DataTable.settings` object is aliased to
35035	 * `jQuery.fn.dataTableExt` through which it may be accessed and
35036	 * manipulated, or `jQuery.fn.dataTable.settings`.
35037	 *  @member
35038	 *  @type array
35039	 *  @default []
35040	 *  @private
35041	 */
35042	DataTable.settings = [];
35043
35044	/**
35045	 * Object models container, for the various models that DataTables has
35046	 * available to it. These models define the objects that are used to hold
35047	 * the active state and configuration of the table.
35048	 *  @namespace
35049	 */
35050	DataTable.models = {};
35051
35052
35053
35054	/**
35055	 * Template object for the way in which DataTables holds information about
35056	 * search information for the global filter and individual column filters.
35057	 *  @namespace
35058	 */
35059	DataTable.models.oSearch = {
35060		/**
35061		 * Flag to indicate if the filtering should be case insensitive or not
35062		 *  @type boolean
35063		 *  @default true
35064		 */
35065		"bCaseInsensitive": true,
35066
35067		/**
35068		 * Applied search term
35069		 *  @type string
35070		 *  @default <i>Empty string</i>
35071		 */
35072		"sSearch": "",
35073
35074		/**
35075		 * Flag to indicate if the search term should be interpreted as a
35076		 * regular expression (true) or not (false) and therefore and special
35077		 * regex characters escaped.
35078		 *  @type boolean
35079		 *  @default false
35080		 */
35081		"bRegex": false,
35082
35083		/**
35084		 * Flag to indicate if DataTables is to use its smart filtering or not.
35085		 *  @type boolean
35086		 *  @default true
35087		 */
35088		"bSmart": true
35089	};
35090
35091
35092
35093
35094	/**
35095	 * Template object for the way in which DataTables holds information about
35096	 * each individual row. This is the object format used for the settings
35097	 * aoData array.
35098	 *  @namespace
35099	 */
35100	DataTable.models.oRow = {
35101		/**
35102		 * TR element for the row
35103		 *  @type node
35104		 *  @default null
35105		 */
35106		"nTr": null,
35107
35108		/**
35109		 * Array of TD elements for each row. This is null until the row has been
35110		 * created.
35111		 *  @type array nodes
35112		 *  @default []
35113		 */
35114		"anCells": null,
35115
35116		/**
35117		 * Data object from the original data source for the row. This is either
35118		 * an array if using the traditional form of DataTables, or an object if
35119		 * using mData options. The exact type will depend on the passed in
35120		 * data from the data source, or will be an array if using DOM a data
35121		 * source.
35122		 *  @type array|object
35123		 *  @default []
35124		 */
35125		"_aData": [],
35126
35127		/**
35128		 * Sorting data cache - this array is ostensibly the same length as the
35129		 * number of columns (although each index is generated only as it is
35130		 * needed), and holds the data that is used for sorting each column in the
35131		 * row. We do this cache generation at the start of the sort in order that
35132		 * the formatting of the sort data need be done only once for each cell
35133		 * per sort. This array should not be read from or written to by anything
35134		 * other than the master sorting methods.
35135		 *  @type array
35136		 *  @default null
35137		 *  @private
35138		 */
35139		"_aSortData": null,
35140
35141		/**
35142		 * Per cell filtering data cache. As per the sort data cache, used to
35143		 * increase the performance of the filtering in DataTables
35144		 *  @type array
35145		 *  @default null
35146		 *  @private
35147		 */
35148		"_aFilterData": null,
35149
35150		/**
35151		 * Filtering data cache. This is the same as the cell filtering cache, but
35152		 * in this case a string rather than an array. This is easily computed with
35153		 * a join on `_aFilterData`, but is provided as a cache so the join isn't
35154		 * needed on every search (memory traded for performance)
35155		 *  @type array
35156		 *  @default null
35157		 *  @private
35158		 */
35159		"_sFilterRow": null,
35160
35161		/**
35162		 * Cache of the class name that DataTables has applied to the row, so we
35163		 * can quickly look at this variable rather than needing to do a DOM check
35164		 * on className for the nTr property.
35165		 *  @type string
35166		 *  @default <i>Empty string</i>
35167		 *  @private
35168		 */
35169		"_sRowStripe": "",
35170
35171		/**
35172		 * Denote if the original data source was from the DOM, or the data source
35173		 * object. This is used for invalidating data, so DataTables can
35174		 * automatically read data from the original source, unless uninstructed
35175		 * otherwise.
35176		 *  @type string
35177		 *  @default null
35178		 *  @private
35179		 */
35180		"src": null,
35181
35182		/**
35183		 * Index in the aoData array. This saves an indexOf lookup when we have the
35184		 * object, but want to know the index
35185		 *  @type integer
35186		 *  @default -1
35187		 *  @private
35188		 */
35189		"idx": -1
35190	};
35191
35192
35193	/**
35194	 * Template object for the column information object in DataTables. This object
35195	 * is held in the settings aoColumns array and contains all the information that
35196	 * DataTables needs about each individual column.
35197	 *
35198	 * Note that this object is related to {@link DataTable.defaults.column}
35199	 * but this one is the internal data store for DataTables's cache of columns.
35200	 * It should NOT be manipulated outside of DataTables. Any configuration should
35201	 * be done through the initialisation options.
35202	 *  @namespace
35203	 */
35204	DataTable.models.oColumn = {
35205		/**
35206		 * Column index. This could be worked out on-the-fly with $.inArray, but it
35207		 * is faster to just hold it as a variable
35208		 *  @type integer
35209		 *  @default null
35210		 */
35211		"idx": null,
35212
35213		/**
35214		 * A list of the columns that sorting should occur on when this column
35215		 * is sorted. That this property is an array allows multi-column s
35215orting
35216		 * to be defined for a column (for example first name / last name columns
35217		 * would benefit from this). The values are integers pointing to the
35218		 * columns to be sorted on (typically it will be a single integer pointing
35219		 * at itself, but that doesn't need to be the case).
35220		 *  @type array
35221		 */
35222		"aDataSort": null,
35223
35224		/**
35225		 * Define the sorting directions that are applied to the column, in sequence
35226		 * as the column is repeatedly sorted upon - i.e. the first value is used
35227		 * as the sorting direction when the column if first sorted (clicked on).
35228		 * Sort it again (click again) and it will move on to the next index.
35229		 * Repeat until loop.
35230		 *  @type array
35231		 */
35232		"asSorting": null,
35233
35234		/**
35235		 * Flag to indicate if the column is searchable, and thus should be included
35236		 * in the filtering or not.
35237		 *  @type boolean
35238		 */
35239		"bSearchable": null,
35240
35241		/**
35242		 * Flag to indicate if the column is sortable or not.
35243		 *  @type boolean
35244		 */
35245		"bSortable": null,
35246
35247		/**
35248		 * Flag to indicate if the column is currently visible in the table or not
35249		 *  @type boolean
35250		 */
35251		"bVisible": null,
35252
35253		/**
35254		 * Store for manual type assignment using the `column.type` option. This
35255		 * is held in store so we can manipulate the column's `sType` property.
35256		 *  @type string
35257		 *  @default null
35258		 *  @private
35259		 */
35260		"_sManualType": null,
35261
35262		/**
35263		 * Flag to indicate if HTML5 data attributes should be used as the data
35264		 * source for filtering or sorting. True is either are.
35265		 *  @type boolean
35266		 *  @default false
35267		 *  @private
35268		 */
35269		"_bAttrSrc": false,
35270
35271		/**
35272		 * Developer definable function that is called whenever a cell is created (Ajax source,
35273		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
35274		 * allowing you to modify the DOM element (add background colour for example) when the
35275		 * element is available.
35276		 *  @type function
35277		 *  @param {element} nTd The TD node that has been created
35278		 *  @param {*} sData The Data for the cell
35279		 *  @param {array|object} oData The data for the whole row
35280		 *  @param {int} iRow The row index for the aoData data store
35281		 *  @default null
35282		 */
35283		"fnCreatedCell": null,
35284
35285		/**
35286		 * Function to get data from a cell in a column. You should <b>never</b>
35287		 * access data directly through _aData internally in DataTables - always use
35288		 * the method attached to this property. It allows mData to function as
35289		 * required. This function is automatically assigned by the column
35290		 * initialisation method
35291		 *  @type function
35292		 *  @param {array|object} oData The data array/object for the array
35293		 *    (i.e. aoData[]._aData)
35294		 *  @param {string} sSpecific The specific data type you want to get -
35295		 *    'display', 'type' 'filter' 'sort'
35296		 *  @returns {*} The data for the cell from the given row's data
35297		 *  @default null
35298		 */
35299		"fnGetData": null,
35300
35301		/**
35302		 * Function to set data for a cell in the column. You should <b>never</b>
35303		 * set the data directly to _aData internally in DataTables - always use
35304		 * this method. It allows mData to function as required. This function
35305		 * is automatically assigned by the column initialisation method
35306		 *  @type function
35307		 *  @param {array|object} oData The data array/object for the array
35308		 *    (i.e. aoData[]._aData)
35309		 *  @param {*} sValue Value to set
35310		 *  @default null
35311		 */
35312		"fnSetData": null,
35313
35314		/**
35315		 * Property to read the value for the cells in the column from the data
35316		 * source array / object. If null, then the default content is used, if a
35317		 * function is given then the return from the function is used.
35318		 *  @type function|int|string|null
35319		 *  @default null
35320		 */
35321		"mData": null,
35322
35323		/**
35324		 * Partner property to mData which is used (only when defined) to get
35325		 * the data - i.e. it is basically the same as mData, but without the
35326		 * 'set' option, and also the data fed to it is the result from mData.
35327		 * This is the rendering method to match the data method of mData.
35328		 *  @type function|int|string|null
35329		 *  @default null
35330		 */
35331		"mRender": null,
35332
35333		/**
35334		 * Unique header TH/TD element for this column - this is what the sorting
35335		 * listener is attached to (if sorting is enabled.)
35336		 *  @type node
35337		 *  @default null
35338		 */
35339		"nTh": null,
35340
35341		/**
35342		 * Unique footer TH/TD element for this column (if there is one). Not used
35343		 * in DataTables as such, but can be used for plug-ins to reference the
35344		 * footer for each column.
35345		 *  @type node
35346		 *  @default null
35347		 */
35348		"nTf": null,
35349
35350		/**
35351		 * The class to apply to all TD elements in the table's TBODY for the column
35352		 *  @type string
35353		 *  @default null
35354		 */
35355		"sClass": null,
35356
35357		/**
35358		 * When DataTables calculates the column widths to assign to each column,
35359		 * it finds the longest string in each column and then constructs a
35360		 * temporary table and reads the widths from that. The problem with this
35361		 * is that "mmm" is much wider then "iiii", but the latter is a longer
35362		 * string - thus the calculation can go wrong (doing it properly and putting
35363		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
35364		 * a "work around" we provide this option. It will append its value to the
35365		 * text that is found to be the longest string for the column - i.e. padding.
35366		 *  @type string
35367		 */
35368		"sContentPadding": null,
35369
35370		/**
35371		 * Allows a default value to be given for a column's data, and will be used
35372		 * whenever a null data source is encountered (this can be because mData
35373		 * is set to null, or because the data source itself is null).
35374		 *  @type string
35375		 *  @default null
35376		 */
35377		"sDefaultContent": null,
35378
35379		/**
35380		 * Name for the column, allowing reference to the column by name as well as
35381		 * by index (needs a lookup to work by name).
35382		 *  @type string
35383		 */
35384		"sName": null,
35385
35386		/**
35387		 * Custom sorting data type - defines which of the available plug-ins in
35388		 * afnSortData the custom sorting will use - if any is defined.
35389		 *  @type string
35390		 *  @default std
35391		 */
35392		"sSortDataType": 'std',
35393
35394		/**
35395		 * Class to be applied to the header element when sorting on this column
35396		 *  @type string
35397		 *  @default null
35398		 */
35399		"sSortingClass": null,
35400
35401		/**
35402		 * Class to be applied to the header element when sorting on this column -
35403		 * when jQuery UI theming is used.
35404		 *  @type string
35405		 *  @default null
35406		 */
35407		"sSortingClassJUI": null,
35408
35409		/**
35410		 * Title of the column - what is seen in the TH element (nTh).
35411		 *  @type string
35412		 */
35413		"sTitle": null,
35414
35415		/**
35416		 * Column sorting and filtering type
35417		 *  @type string
35418		 *  @default null
35419		 */
35420		"sType": null,
35421
35422		/**
35423		 * Width of the column
35424		 *  @type string
35425		 *  @default null
35426		 */
35427		"sWidth": null,
35428
35429		/**
35430		 * Width of the column when it was first "encountered"
35431		 *  @type string
35432		 *  @default null
35433		 */
35434		"sWidthOrig": null
35435	};
35436
35437
35438	/*
35439	 * Developer note: The properties of the object below are given in Hungarian
35440	 * notation, that was used as the interface for DataTables prior to v1.10, however
35441	 * from v1.10 onwards the primary interface is camel case. In order to avoid
35442	 * breaking backwards compatibility utterly with this change, the Hungarian
35443	 * version is still, internally the primary interface, but is is not documented
35444	 * - hence the @name tags in each doc comment. This allows a Javascript function
35445	 * to create a map from Hungarian notation to camel case (going the other direction
35446	 * would require each property to be listed, which would at around 3K to the size
35447	 * of DataTables, while this method is about a 0.5K hit.
35448	 *
35449	 * Ultimately this does pave the way for Hungarian notation to be dropped
35450	 * completely, but that is a massive amount of work and will break current
35451	 * installs (therefore is on-hold until v2).
35452	 */
35453
35454	/**
35455	 * Initialisation options that can be given to DataTables at initialisation
35456	 * time.
35457	 *  @namespace
35458	 */
35459	DataTable.defaults = {
35460		/**
35461		 * An array of data to use for the table, passed in at initialisation which
35462		 * will be used in preference to any data which is already in the DOM. This is
35463		 * particularly useful for constructing tables purely in Javascript, for
35464		 * example with a custom Ajax call.
35465		 *  @type array
35466		 *  @default null
35467		 *
35468		 *  @dtopt Option
35469		 *  @name DataTable.defaults.data
35470		 *
35471		 *  @example
35472		 *    // Using a 2D array data source
35473		 *    $(document).ready( function () {
35474		 *      $('#example').dataTable( {
35475		 *        "data": [
35476		 *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
35477		 *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
35478		 *        ],
35479		 *        "columns": [
35480		 *          { "title": "Engine" },
35481		 *          { "title": "Browser" },
35482		 *          { "title": "Platform" },
35483		 *          { "title": "Version" },
35484		 *          { "title": "Grade" }
35485		 *        ]
35486		 *      } );
35487		 *    } );
35488		 *
35489		 *  @example
35490		 *    // Using an array of objects as a data source (`data`)
35491		 *    $(document).ready( function () {
35492		 *      $('#example').dataTable( {
35493		 *        "data": [
35494		 *          {
35495		 *            "engine":   "Trident",
35496		 *            "browser":  "Internet Explorer 4.0",
35497		 *            "platform": "Win 95+",
35498		 *            "version":  4,
35499		 *            "grade":    "X"
35500		 *          },
35501		 *          {
35502		 *            "engine":   "Trident",
35503		 *            "browser":  "Internet Explorer 5.0",
35504		 *            "platform": "Win 95+",
35505		 *            "version":  5,
35506		 *            "grade":    "C"
35507		 *          }
35508		 *        ],
35509		 *        "columns": [
35510		 *          { "title": "Engine",   "data": "engine" },
35511		 *          { "title": "Browser",  "data": "browser" },
35512		 *          { "title": "Platform", "data": "platform" },
35513		 *          { "title": "Version",  "data": "version" },
35514		 *          { "title": "Grade",    "data": "grade" }
35515		 *        ]
35516		 *      } );
35517		 *    } );
35518		 */
35519		"aaData": null,
35520
35521
35522		/**
35523		 * If ordering is enabled, then DataTables will perform a first pass sort on
35524		 * initialisation. You can define which column(s) the sort is performed
35525		 * upon, and the sorting direction, with this variable. The `sorting` array
35526		 * should contain an array for each column to be sorted initially containing
35527		 * the column's index and a direction string ('asc' or 'desc').
35528		 *  @type array
35529		 *  @default [[0,'asc']]
35530		 *
35531		 *  @dtopt Option
35532		 *  @name DataTable.defaults.order
35533		 *
35534		 *  @example
35535		 *    // Sort by 3rd column first, and then 4th column
35536		 *    $(document).ready( function() {
35537		 *      $('#example').dataTable( {
35538		 *        "order": [[2,'asc'], [3,'desc']]
35539		 *      } );
35540		 *    } );
35541		 *
35542		 *    // No initial sorting
35543		 *    $(document).ready( function() {
35544		 *      $('#example').dataTable( {
35545		 *        "order": []
35546		 *      } );
35547		 *    } );
35548		 */
35549		"aaSorting": [[0,'asc']],
35550
35551
35552		/**
35553		 * This parameter is basically identical to the `sorting` parameter, but
35554		 * cannot be overridden by user interaction with the table. What this means
35555		 * is that you could have a column (visible or hidden) which the sorting
35556		 * will always be forced on first - any sorting after that (from the user)
35557		 * will then be performed as required. This can be useful for grouping rows
35558		 * together.
35559		 *  @type array
35560		 *  @default null
35561		 *
35562		 *  @dtopt Option
35563		 *  @name DataTable.defaults.orderFixed
35564		 *
35565		 *  @example
35566		 *    $(document).ready( function() {
35567		 *      $('#example').dataTable( {
35568		 *        "orderFixed": [[0,'asc']]
35569		 *      } );
35570		 *    } )
35571		 */
35572		"aaSortingFixed": [],
35573
35574
35575		/**
35576		 * DataTables can be instructed to load data to display in the table from a
35577		 * Ajax source. This option defines how that Ajax call is made and where to.
35578		 *
35579		 * The `ajax` property has three different modes of operation, depending on
35580		 * how it is defined. These are:
35581		 *
35582		 * * `string` - Set the URL from where the data should be loaded from.
35583		 * * `object` - Define properties for `jQuery.ajax`.
35584		 * * `function` - Custom data get function
35585		 *
35586		 * `string`
35587		 * --------
35588		 *
35589		 * As a string, the `ajax` property simply defines the URL from which
35590		 * DataTables will load data.
35591		 *
35592		 * `object`
35593		 * --------
35594		 *
35595		 * As an object, the parameters in the object are passed to
35596		 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
35597		 * of the Ajax request. DataTables has a number of default parameters which
35598		 * you can override using this option. Please refer to the jQuery
35599		 * documentation for a full description of the options available, although
35600		 * the following parameters provide additional options in DataTables or
35601		 * require special consideration:
35602		 *
35603		 * * `data` - As with jQuery, `data` can be provided as an object, but it
35604		 *   can also be used as a function to manipulate the data DataTables sends
35605		 *   to the server. The function takes a single parameter, an object of
35606		 *   parameters with the values that DataTables has readied for sending. An
35607		 *   object may be returned which will be merged into the DataTables
35608		 *   defaults, or you can add the items to the object that was passed in and
35609		 *   not return anything from the function. This supersedes `fnServerParams`
35610		 *   from DataTables 1.9-.
35611		 *
35612		 * * `dataSrc` - By default DataTables will look for the property `data` (or
35613		 *   `aaData` for compatibility with DataTables 1.9-) when obtaining data
35614		 *   from an Ajax source or for server-side processing - this parameter
35615		 *   allows that property to be changed. You can use Javascript dotted
35616		 *   object notation to get a data source for multiple levels of nesting, or
35617		 *   it my be used as a function. As a function it takes a single parameter,
35618		 *   the JSON returned from the server, which can be manipulated as
35619		 *   required, with the returned value being that used by DataTables as the
35620		 *   data source for the table. This supersedes `sAjaxDataProp` from
35621		 *   DataTables 1.9-.
35622		 *
35623		 * * `success` - Should not be overridden it is used internally in
35624		 *   DataTables. To manipulate / transform the data returned by the server
35625		 *   use `ajax.dataSrc`, or use `ajax` as a function (see below).
35626		 *
35627		 * `function`
35628		 * ----------
35629		 *
35630		 * As a function, making the Ajax call is left up to yourself allowing
35631		 * complete control of the Ajax request. Indeed, if desired, a method other
35632		 * than Ajax could be used to obtain the required data, such as Web storage
35633		 * or an AIR database.
35634		 *
35635		 * The function is given four parameters and no return is required. The
35636		 * parameters are:
35637		 *
35638		 * 1. _object_ - Data to send to the server
35639		 * 2. _function_ - Callback function that must be executed when the required
35640		 *    data has been obtained. That data should be passed into the callback
35641		 *    as the only parameter
35642		 * 3. _object_ - DataTables settings object for the table
35643		 *
35644		 * Note that this supersedes `fnServerData` from DataTables 1.9-.
35645		 *
35646		 *  @type string|object|function
35647		 *  @default null
35648		 *
35649		 *  @dtopt Option
35650		 *  @name DataTable.defaults.ajax
35651		 *  @since 1.10.0
35652		 *
35653		 * @example
35654		 *   // Get JSON data from a file via Ajax.
35655		 *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
35656		 *   $('#example').dataTable( {
35657		 *     "ajax": "data.json"
35658		 *   } );
35659		 *
35660		 * @example
35661		 *   // Get JSON data from a file via Ajax, using `dataSrc` to change
35662		 *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
35663		 *   $('#example').dataTable( {
35664		 *     "ajax": {
35665		 *       "url": "data.json",
35666		 *       "dataSrc": "tableData"
35667		 *     }
35668		 *   } );
35669		 *
35670		 * @example
35671		 *   // Get JSON data from a file via Ajax, using `dataSrc` to read data
35672		 *   // from a plain array rather than an array in an object
35673		 *   $('#example').dataTable( {
35674		 *     "ajax": {
35675		 *       "url": "data.json",
35676		 *       "dataSrc": ""
35677		 *     }
35678		 *   } );
35679		 *
35680		 * @example
35681		 *   // Manipulate the data returned from the server - add a link to data
35682		 *   // (note this can, should, be done using `render` for the column - this
35683		 *   // is just a simple example of how the data can be manipulated).
35684		 *   $('#example').dataTable( {
35685		 *     "ajax": {
35686		 *       "url": "data.json",
35687		 *       "dataSrc": function ( json ) {
35688		 *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {
35689		 *           json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
35690		 *         }
35691		 *         return json;
35692		 *       }
35693		 *     }
35694		 *   } );
35695		 *
35696		 * @example
35697		 *   // Add data to the request
35698		 *   $('#example').dataTable( {
35699		 *     "ajax": {
35700		 *       "url": "data.json",
35701		 *       "data": function ( d ) {
35702		 *         return {
35703		 *           "extra_search": $('#extra').val()
35704		 *         };
35705		 *       }
35706		 *     }
35707		 *   } );
35708		 *
35709		 * @example
35710		 *   // Send request as POST
35711		 *   $('#example').dataTable( {
35712		 *     "ajax": {
35713		 *       "url": "data.json",
35714		 *       "type": "POST"
35715		 *     }
35716		 *   } );
35717		 *
35718		 * @example
35719		 *   // Get the data from localStorage (could interface with a form for
35720		 *   // adding, editing and removing rows).
35721		 *   $('#example').dataTable( {
35722		 *     "ajax": function (data, callback, settings) {
35723		 *       callback(
35724		 *         JSON.parse( localStorage.getItem('dataTablesData') )
35725		 *       );
35726		 *     }
35727		 *   } );
35728		 */
35729		"ajax": null,
35730
35731
35732		/**
35733		 * This parameter allows you to readily specify the entries in the length drop
35734		 * down menu that DataTables shows when pagination is enabled. It can be
35735		 * either a 1D array of options which will be used for both the displayed
35736		 * option and the value, or a 2D array which will use the array in the first
35737		 * position as the value, and the array in the second position as the
35738		 * displayed options (useful for language strings such as 'All').
35739		 *
35740		 * Note that the `pageLength` property will be automatically set to the
35741		 * first value given in this array, unless `pageLength` is also provided.
35742		 *  @type array
35743		 *  @default [ 10, 25, 50, 100 ]
35744		 *
35745		 *  @dtopt Option
35746		 *  @name DataTable.defaults.lengthMenu
35747		 *
35748		 *  @example
35749		 *    $(document).ready( function() {
35750		 *      $('#example').dataTable( {
35751		 *        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
35752		 *      } );
35753		 *    } );
35754		 */
35755		"aLengthMenu": [ 10, 25, 50, 100 ],
35756
35757
35758		/**
35759		 * The `columns` option in the initialisation parameter allows you to define
35760		 * details about the way individual columns behave. For a full list of
35761		 * column options that can be set, please see
35762		 * {@link DataTable.defaults.column}. Note that if you use `columns` to
35763		 * define your columns, you must have an entry in the array for every single
35764		 * column that you have in your table (these can be null if you don't which
35765		 * to specify any options).
35766		 *  @member
35767		 *
35768		 *  @name DataTable.defaults.column
35769		 */
35770		"aoColumns": null,
35771
35772		/**
35773		 * Very similar to `columns`, `columnDefs` allows you to target a specific
35774		 * column, multiple columns, or all columns, using the `targets` property of
35775		 * each object in the array. This allows great flexibility when creating
35776		 * tables, as the `columnDefs` arrays can be of any length, targeting the
35777		 * columns you specifically want. `columnDefs` may use any of the column
35778		 * options available: {@link DataTable.defaults.column}, but it _must_
35779		 * have `targets` defined in each object in the array. Values in the `targets`
35780		 * array may be:
35781		 *   <ul>
35782		 *     <li>
35782a string - class name will be matched on the TH for the column</li>
35783		 *     <li>0 or a positive integer - column index counting from the left</li>
35784		 *     <li>a negative integer - column index counting from the right</li>
35785		 *     <li>the string "_all" - all columns (i.e. assign a default)</li>
35786		 *   </ul>
35787		 *  @member
35788		 *
35789		 *  @name DataTable.defaults.columnDefs
35790		 */
35791		"aoColumnDefs": null,
35792
35793
35794		/**
35795		 * Basically the same as `search`, this parameter defines the individual column
35796		 * filtering state at initialisation time. The array must be of the same size
35797		 * as the number of columns, and each element be an object with the parameters
35798		 * `search` and `escapeRegex` (the latter is optional). 'null' is also
35799		 * accepted and the default will be used.
35800		 *  @type array
35801		 *  @default []
35802		 *
35803		 *  @dtopt Option
35804		 *  @name DataTable.defaults.searchCols
35805		 *
35806		 *  @example
35807		 *    $(document).ready( function() {
35808		 *      $('#example').dataTable( {
35809		 *        "searchCols": [
35810		 *          null,
35811		 *          { "search": "My filter" },
35812		 *          null,
35813		 *          { "search": "^[0-9]", "escapeRegex": false }
35814		 *        ]
35815		 *      } );
35816		 *    } )
35817		 */
35818		"aoSearchCols": [],
35819
35820
35821		/**
35822		 * An array of CSS classes that should be applied to displayed rows. This
35823		 * array may be of any length, and DataTables will apply each class
35824		 * sequentially, looping when required.
35825		 *  @type array
35826		 *  @default null <i>
35826Will take the values determined by the `oClasses.stripe*`
35827		 *    options</i>
35828		 *
35829		 *  @dtopt Option
35830		 *  @name DataTable.defaults.stripeClasses
35831		 *
35832		 *  @example
35833		 *    $(document).ready( function() {
35834		 *      $('#example').dataTable( {
35835		 *        "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
35836		 *      } );
35837		 *    } )
35838		 */
35839		"asStripeClasses": null,
35840
35841
35842		/**
35843		 * Enable or disable automatic column width calculation. This can be disabled
35844		 * as an optimisation (it takes some time to calculate the widths) if the
35845		 * tables widths are passed in using `columns`.
35846		 *  @type boolean
35847		 *  @default true
35848		 *
35849		 *  @dtopt Features
35850		 *  @name DataTable.defaults.autoWidth
35851		 *
35852		 *  @example
35853		 *    $(document).ready( function () {
35854		 *      $('#example').dataTable( {
35855		 *        "autoWidth": false
35856		 *      } );
35857		 *    } );
35858		 */
35859		"bAutoWidth": true,
35860
35861
35862		/**
35863		 * Deferred rendering can provide DataTables with a huge speed boost when you
35864		 * are using an Ajax or JS data source for the table. This option, when set to
35865		 * true, will cause DataTables to defer the creation of the table elements for
35866		 * each row until they are needed for a draw - saving a significant amount of
35867		 * time.
35868		 *  @type boolean
35869		 *  @default false
35870		 *
35871		 *  @dtopt Features
35872		 *  @name DataTable.defaults.deferRender
35873		 *
35874		 *  @example
35875		 *    $(document).ready( function() {
35876		 *      $('#example').dataTable( {
35877		 *        "ajax": "sources/arrays.txt",
35878		 *        "deferRender": true
35879		 *      } );
35880		 *    } );
35881		 */
35882		"bDeferRender": false,
35883
35884
35885		/**
35886		 * Replace a DataTable which matches the given selector and replace it with
35887		 * one which has the properties of the new initialisation object passed. If no
35888		 * table matches the selector, then the new DataTable will be constructed as
35889		 * per normal.
35890		 *  @type boolean
35891		 *  @default false
35892		 *
35893		 *  @dtopt Options
35894		 *  @name DataTable.defaults.destroy
35895		 *
35896		 *  @example
35897		 *    $(document).ready( function() {
35898		 *      $('#example').dataTable( {
35899		 *        "srollY": "200px",
35900		 *        "paginate": false
35901		 *      } );
35902		 *
35903		 *      // Some time later....
35904		 *      $('#example').dataTable( {
35905		 *        "filter": false,
35906		 *        "destroy": true
35907		 *      } );
35908		 *    } );
35909		 */
35910		"bDestroy": false,
35911
35912
35913		/**
35914		 * Enable or disable filtering of data. Filtering in DataTables is "smart" in
35915		 * that it allows the end user to input multiple words (space separated) and
35916		 * will match a row containing those words, even if not in the order that was
35917		 * specified (this allow matching across multiple columns). Note that if you
35918		 * wish to use filtering in DataTables this must remain 'true' - to remove the
35919		 * default filtering input box and retain filtering abilities, please use
35920		 * {@link DataTable.defaults.dom}.
35921		 *  @type boolean
35922		 *  @default true
35923		 *
35924		 *  @dtopt Features
35925		 *  @name DataTable.defaults.searching
35926		 *
35927		 *  @example
35928		 *    $(document).ready( function () {
35929		 *      $('#example').dataTable( {
35930		 *        "searching": false
35931		 *      } );
35932		 *    } );
35933		 */
35934		"bFilter": true,
35935
35936
35937		/**
35938		 * Enable or disable the table information display. This shows information
35939		 * about the data that is currently visible on the page, including information
35940		 * about filtered data if that action is being performed.
35941		 *  @type boolean
35942		 *  @default true
35943		 *
35944		 *  @dtopt Features
35945		 *  @name DataTable.defaults.info
35946		 *
35947		 *  @example
35948		 *    $(document).ready( function () {
35949		 *      $('#example').dataTable( {
35950		 *        "info": false
35951		 *      } );
35952		 *    } );
35953		 */
35954		"bInfo": true,
35955
35956
35957		/**
35958		 * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
35959		 * slightly different and additional mark-up from what DataTables has
35960		 * traditionally used).
35961		 *  @type boolean
35962		 *  @default false
35963		 *
35964		 *  @dtopt Features
35965		 *  @name DataTable.defaults.jQueryUI
35966		 *
35967		 *  @example
35968		 *    $(document).ready( function() {
35969		 *      $('#example').dataTable( {
35970		 *        "jQueryUI": true
35971		 *      } );
35972		 *    } );
35973		 */
35974		"bJQueryUI": false,
35975
35976
35977		/**
35978		 * Allows the end user to select the size of a formatted page from a select
35979		 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
35980		 *  @type boolean
35981		 *  @default true
35982		 *
35983		 *  @dtopt Features
35984		 *  @name DataTable.defaults.lengthChange
35985		 *
35986		 *  @example
35987		 *    $(document).ready( function () {
35988		 *      $('#example').dataTable( {
35989		 *        "lengthChange": false
35990		 *      } );
35991		 *    } );
35992		 */
35993		"bLengthChange": true,
35994
35995
35996		/**
35997		 * Enable or disable pagination.
35998		 *  @type boolean
35999		 *  @default true
36000		 *
36001		 *  @dtopt Features
36002		 *  @name DataTable.defaults.paging
36003		 *
36004		 *  @example
36005		 *    $(document).ready( function () {
36006		 *      $('#example').dataTable( {
36007		 *        "paging": false
36008		 *      } );
36009		 *    } );
36010		 */
36011		"bPaginate": true,
36012
36013
36014		/**
36015		 * Enable or disable the display of a 'processing' indicator when the table is
36016		 * being processed (e.g. a sort). This is particularly useful for tables with
36017		 * large amounts of data where it can take a noticeable amount of time to sort
36018		 * the entries.
36019		 *  @type boolean
36020		 *  @default false
36021		 *
36022		 *  @dtopt Features
36023		 *  @name DataTable.defaults.processing
36024		 *
36025		 *  @example
36026		 *    $(document).ready( function () {
36027		 *      $('#example').dataTable( {
36028		 *        "processing": true
36029		 *      } );
36030		 *    } );
36031		 */
36032		"bProcessing": false,
36033
36034
36035		/**
36036		 * Retrieve the DataTables object for the given selector. Note that if the
36037		 * table has already been initialised, this parameter will cause DataTables
36038		 * to simply return the object that has already been set up - it will not take
36039		 * account of any changes you might have made to the initialisation object
36040		 * passed to DataTables (setting this parameter to true is an acknowledgement
36041		 * that you understand this). `destroy` can be used to reinitialise a table if
36042		 * you need.
36043		 *  @type boolean
36044		 *  @default false
36045		 *
36046		 *  @dtopt Options
36047		 *  @name DataTable.defaults.retrieve
36048		 *
36049		 *  @example
36050		 *    $(document).ready( function() {
36051		 *      initTable();
36052		 *      tableActions();
36053		 *    } );
36054		 *
36055		 *    function initTable ()
36056		 *    {
36057		 *      return $('#example').dataTable( {
36058		 *        "scrollY": "200px",
36059		 *        "paginate": false,
36060		 *        "retrieve": true
36061		 *      } );
36062		 *    }
36063		 *
36064		 *    function tableActions ()
36065		 *    {
36066		 *      var table = initTable();
36067		 *      // perform API operations with oTable
36068		 *    }
36069		 */
36070		"bRetrieve": false,
36071
36072
36073		/**
36074		 * When vertical (y) scrolling is enabled, DataTables will force the height of
36075		 * the table's viewport to the given height at all times (useful for layout).
36076		 * However, this can look odd when filtering data down to a small data set,
36077		 * and the footer is left "floating" further down. This parameter (when
36078		 * enabled) will cause DataTables to collapse the table's viewport down when
36079		 * the result set will fit within the given Y height.
36080		 *  @type boolean
36081		 *  @default false
36082		 *
36083		 *  @dtopt Options
36084		 *  @name DataTable.defaults.scrollCollapse
36085		 *
36086		 *  @example
36087		 *    $(document).ready( function() {
36088		 *      $('#example').dataTable( {
36089		 *        "scrollY": "200",
36090		 *        "scrollCollapse": true
36091		 *      } );
36092		 *    } );
36093		 */
36094		"bScrollCollapse": false,
36095
36096
36097		/**
36098		 * Configure DataTables to use server-side processing. Note that the
36099		 * `ajax` parameter must also be given in order to give DataTables a
36100		 * source to obtain the required data for each draw.
36101		 *  @type boolean
36102		 *  @default false
36103		 *
36104		 *  @dtopt Features
36105		 *  @dtopt Server-side
36106		 *  @name DataTable.defaults.serverSide
36107		 *
36108		 *  @example
36109		 *    $(document).ready( function () {
36110		 *      $('#example').dataTable( {
36111		 *        "serverSide": true,
36112		 *        "ajax": "xhr.php"
36113		 *      } );
36114		 *    } );
36115		 */
36116		"bServerSide": false,
36117
36118
36119		/**
36120		 * Enable or disable sorting of columns. Sorting of individual columns can be
36121		 * disabled by the `sortable` option for each column.
36122		 *  @type boolean
36123		 *  @default true
36124		 *
36125		 *  @dtopt Features
36126		 *  @name DataTable.defaults.ordering
36127		 *
36128		 *  @example
36129		 *    $(document).ready( function () {
36130		 *      $('#example').dataTable( {
36131		 *        "ordering": false
36132		 *      } );
36133		 *    } );
36134		 */
36135		"bSort": true,
36136
36137
36138		/**
36139		 * Enable or display DataTables' ability to sort multiple columns at the
36140		 * same time (activated by shift-click by the user).
36141		 *  @type boolean
36142		 *  @default true
36143		 *
36144		 *  @dtopt Options
36145		 *  @name DataTable.defaults.orderMulti
36146		 *
36147		 *  @example
36148		 *    // Disable multiple column sorting ability
36149		 *    $(document).ready( function () {
36150		 *      $('#example').dataTable( {
36151		 *        "orderMulti": false
36152		 *      } );
36153		 *    } );
36154		 */
36155		"bSortMulti": true,
36156
36157
36158		/**
36159		 * Allows control over whether DataTables should use the top (true) unique
36160		 * cell that is found for a single column, or the bottom (false - default).
36161		 * This is useful when using complex headers.
36162		 *  @type boolean
36163		 *  @default false
36164		 *
36165		 *  @dtopt Options
36166		 *  @name DataTable.defaults.orderCellsTop
36167		 *
36168		 *  @example
36169		 *    $(document).ready( function() {
36170		 *      $('#example').dataTable( {
36171		 *        "orderCellsTop": true
36172		 *      } );
36173		 *    } );
36174		 */
36175		"bSortCellsTop": false,
36176
36177
36178		/**
36179		 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
36180		 * `sorting\_3` to the columns which are currently being sorted on. This is
36181		 * presented as a feature switch as it can increase processing time (while
36182		 * classes are removed and added) so for large data sets you might want to
36183		 * turn this off.
36184		 *  @type boolean
36185		 *  @default true
36186		 *
36187		 *  @dtopt Features
36188		 *  @name DataTable.defaults.orderClasses
36189		 *
36190		 *  @example
36191		 *    $(document).ready( function () {
36192		 *      $('#example').dataTable( {
36193		 *        "orderClasses": false
36194		 *      } );
36195		 *    } );
36196		 */
36197		"bSortClasses": true,
36198
36199
36200		/**
36201		 * Enable or disable state saving. When enabled HTML5 `localStorage` will be
36202		 * used to save table display information such as pagination information,
36203		 * display length, filtering and sorting. As such when the end user reloads
36204		 * the page the display display will match what thy had previously set up.
36205		 *
36206		 * Due to the use of `localStorage` the default state saving is not supported
36207		 * in IE6 or 7. If state saving is required in those browsers, use
36208		 * `stateSaveCallback` to provide a storage solution such as cookies.
36209		 *  @type boolean
36210		 *  @default false
36211		 *
36212		 *  @dtopt Features
36213		 *  @name DataTable.defaults.stateSave
36214		 *
36215		 *  @example
36216		 *    $(document).ready( function () {
36217		 *      $('#example').dataTable( {
36218		 *        "stateSave": true
36219		 *      } );
36220		 *    } );
36221		 */
36222		"bStateSave": false,
36223
36224
36225		/**
36226		 * This function is called when a TR element is created (and all TD child
36227		 * elements have been inserted), or registered if using a DOM source, allowing
36228		 * manipulation of the TR element (adding classes etc).
36229		 *  @type function
36230		 *  @param {node} row "TR" element for the current row
36231		 *  @param {array} data Raw data array for this row
36232		 *  @param {int} dataIndex The index of this row in the internal aoData array
36233		 *
36234		 *  @dtopt Callbacks
36235		 *  @name DataTable.defaults.createdRow
36236		 *
36237		 *  @example
36238		 *    $(document).ready( function() {
36239		 *      $('#example').dataTable( {
36240		 *        "createdRow": function( row, data, dataIndex ) {
36241		 *          // Bold the grade for all 'A' grade browsers
36242		 *          if ( data[4] == "A" )
36243		 *          {
36244		 *            $('td:eq(4)', row).html( '<b>A</b>' );
36245		 *          }
36246		 *        }
36247		 *      } );
36248		 *    } );
36249		 */
36250		"fnCreatedRow": null,
36251
36252
36253		/**
36254		 * This function is called on every 'draw' event, and allows you to
36255		 * dynamically modify any aspect you want about the created DOM.
36256		 *  @type function
36257		 *  @param {object} settings DataTables settings object
36258		 *
36259		 *  @dtopt Callbacks
36260		 *  @name DataTable.defaults.drawCallback
36261		 *
36262		 *  @example
36263		 *    $(document).ready( function() {
36264		 *      $('#example').dataTable( {
36265		 *        "drawCallback": function( settings ) {
36266		 *          alert( 'DataTables has redrawn the table' );
36267		 *        }
36268		 *      } );
36269		 *    } );
36270		 */
36271		"fnDrawCallback": null,
36272
36273
36274		/**
36275		 * Identical to fnHeaderCallback() but for the table footer this function
36276		 * allows you to modify the table footer on every 'draw' event.
36277		 *  @type function
36278		 *  @param {node} foot "TR" element for the footer
36279		 *  @param {array} data Full table data (as derived from the original HTML)
36280		 *  @param {int} start Index for the current display starting point in the
36281		 *    display array
36282		 *  @param {int} end Index for the current display ending point in the
36283		 *    display array
36284		 *  @param {array int} display Index array to translate the visual position
36285		 *    to the full data array
36286		 *
36287		 *  @dtopt Callbacks
36288		 *  @name DataTable.defaults.footerCallback
36289		 *
36290		 *  @example
36291		 *    $(document).ready( function() {
36292		 *      $('#example').dataTable( {
36293		 *        "footerCallback": function( tfoot, data, start, end, display ) {
36294		 *          tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
36295		 *        }
36296		 *      } );
36297		 *    } )
36298		 */
36299		"fnFooterCallback": null,
36300
36301
36302		/**
36303		 * When rendering large numbers in the information element for the table
36304		 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
36305		 * to have a comma separator for the 'thousands' units (e.g. 1 million is
36306		 * rendered as "1,000,000") to help readability for the end user. This
36307		 * function will override the default method DataTables uses.
36308		 *  @type function
36309		 *  @member
36310		 *  @param {int} toFormat number to be formatted
36311		 *  @returns {string} formatted string for DataTables to show the number
36312		 *
36313		 *  @dtopt Callbacks
36314		 *  @name DataTable.defaults.formatNumber
36315		 *
36316		 *  @example
36317		 *    // Format a number using a single quote for the separator (note that
36318		 *    // this can also be done with the language.thousands option)
36319		 *    $(document).ready( function() {
36320		 *      $('#example').dataTable( {
36321		 *        "formatNumber": function ( toFormat ) {
36322		 *          return toFormat.toString().replace(
36323		 *            /\B(?=(\d{3})+(?!\d))/g, "'"
36324		 *          );
36325		 *        };
36326		 *      } );
36327		 *    } );
36328		 */
36329		"fnFormatNumber": function ( toFormat ) {
36330			return toFormat.toString().replace(
36331				/\B(?=(\d{3})+(?!\d))/g,
36332				this.oLanguage.sThousands
36333			);
36334		},
36335
36336
36337		/**
36338		 * This function is called on every 'draw' event, and allows you to
36339		 * dynamically modify the header row. This can be used to calculate and
36340		 * display useful information about the table.
36341		 *  @type function
36342		 *  @param {node} head "TR" element for the header
36343		 *  @param {array} data Full table data (as derived from the original HTML)
36344		 *  @param {int} start Index for the current display starting point in the
36345		 *    display array
36346		 *  @param {int} end Index for the current display ending point in the
36347		 *    display array
36348		 *  @param {array int} display Index array to translate the visual position
36349		 *    to the full data array
36350		 *
36351		 *  @dtopt Callbacks
36352		 *  @name DataTable.defaults.headerCallback
36353		 *
36354		 *  @example
36355		 *    $(document).ready( function() {
36356		 *      $('#example').dataTable( {
36357		 *        "fheaderCallback": function( head, data, start, end, display ) {
36358		 *          head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
36359		 *        }
36360		 *      } );
36361		 *    } )
36362		 */
36363		"fnHeaderCallback": null,
36364
36365
36366		/**
36367		 * The information element can be used to convey information about the current
36368		 * state of the table. Although the internationalisation options presented by
36369		 * DataTables are quite capable of dealing with most customisations, there may
36370		 * be times where you wish to customise the string further. This callback
36371		 * allows you to do exactly that.
36372		 *  @type function
36373		 *  @param {object} oSettings DataTables settings object
36374		 *  @param {int} start Starting position in data for the draw
36375		 *  @param {int} end End position in data for the draw
36376		 *  @param {int} max Total number of rows in the table (regardless of
36377		 *    filtering)
36378		 *  @param {int} total Total number of rows in the data set, after filtering
36379		 *  @param {string} pre The string that DataTables has formatted using it's
36380		 *    own rules
36381		 *  @returns {string} The string to be displayed in the information element.
36382		 *
36383		 *  @dtopt Callbacks
36384		 *  @name DataTable.defaults.infoCallback
36385		 *
36386		 *  @example
36387		 *    $('#example').dataTable( {
36388		 *      "infoCallback": function( settings, start, end, max, total, pre ) {
36389		 *        return start +" to "+ end;
36390		 *      }
36391		 *    } );
36392		 */
36393		"fnInfoCallback": null,
36394
36395
36396		/**
36397		 * Called when the table has been initialised. Normally DataTables will
36398		 * initialise sequentially and there will be no need for this function,
36399		 * however, this does not hold true when using external language information
36400		 * since that is obtained using an async XHR call.
36401		 *  @type function
36402		 *  @param {object} settings DataTables settings object
36403		 *  @param {object} json The JSON object request from the server - only
36404		 *    present if client-side Ajax sourced data is used
36405		 *
36406		 *  @dtopt Callbacks
36407		 *  @name DataTable.defaults.initComplete
36408		 *
36409		 *  @example
36410		 *    $(document).ready( function() {
36411		 *      $('#example').dataTable( {
36412		 *        "initComplete": function(settings, json) {
36413		 *          alert( 'DataTables has finished its initialisation.' );
36414		 *        }
36415		 *      } );
36416		 *    } )
36417		 */
36418		"fnInitComplete": null,
36419
36420
36421		/**
36422		 * Called at the very start of each table draw and can be used to cancel the
36423		 * draw by returning false, any other return (including undefined) results in
36424		 * the full draw occurring).
36425		 *  @type function
36426		 *  @param {object} settings DataTables settings object
36427		 *  @returns {boolean} False will cancel the draw, anything else (including no
36428		 *    return) will allow it to complete.
36429		 *
36430		 *  @dtopt Callbacks
36431		 *  @name DataTable.defaults.preDrawCallback
36432		 *
36433		 *  @example
36434		 *    $(document).ready( function() {
36435		 *      $('#example').dataTable( {
36436		 *        "preDrawCallback": function( settings ) {
36437		 *          if ( $('#test').val() == 1 ) {
36438		 *            return false;
36439		 *          }
36440		 *        }
36441		 *      } );
36442		 *    } );
36443		 */
36444		"fnPreDrawCallback": null,
36445
36446
36447		/**
36448		 * This function allows you to 'post process' each row after it have been
36449		 * generated for each table draw, but before it is rendered on screen. This
36450		 * function might be used for setting the row class name etc.
36451		 *  @type function
36452		 *  @param {node} row "TR" element for the current row
36453		 *  @param {array} data Raw data array for this row
36454		 *  @param {int} displayIndex The display index for the current table draw
36455		 *  @param {int} displayIndexFull The index of the data in the full list of
36456		 *    rows (after filtering)
36457		 *
36458		 *  @dtopt Callbacks
36459		 *  @name DataTable.defaults.rowCallback
36460		 *
36461		 *  @example
36462		 *    $(document).ready( function() {
36463		 *      $('#example').dataTable( {
36464		 *        "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
36465		 *          // Bold the grade for all 'A' grade browsers
36466		 *          if ( data[4] == "A" ) {
36467		 *            $('td:eq(4)', row).html( '<b>A</b>' );
36468		 *          }
36469		 *        }
36470		 *      } );
36471		 *    } );
36472		 */
36473		"fnRowCallback": null,
36474
36475
36476		/**
36477		 * __Deprecated__ The functionality provided by this parameter has now been
36478		 * superseded by that provided through `ajax`, which should be used instead.
36479		 *
36480		 * This parameter allows you to override the default function which obtains
36481		 * the data from the server so something more suitable for your application.
36482		 * For example you could use POST data, or pull information from a Gears or
36483		 * AIR database.
36484		 *  @type function
36485		 *  @member
36486		 *  @param {string} source HTTP source to obtain the data from (`ajax`)
36487		 *  @param {array} data A key/value pair object containing the data to send
36488		 *    to the server
36489		 *  @param {function} callback to be called on completion of the data get
36490		 *    process that will draw the data on the page.
36491		 *  @param {object} settings DataTables settings object
36492		 *
36493		 *  @dtopt Callbacks
36494		 *  @dtopt Server-side
36495		 *  @name DataTable.defaults.serverData
36496		 *
36497		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
36498		 */
36499		"fnServerData": null,
36500
36501
36502		/**
36503		 * __Deprecated__ The functionality provided by this parameter has now been
36504		 * superseded by that provided through `ajax`, which should be used instead.
36505		 *
36506		 *  It is often useful to send extra data to the server when making an Ajax
36507		 * request - for example custom filtering information, and this callback
36508		 * function makes it trivial to send extra information to the server. The
36509		 * passed in parameter is the data set that has been constructed by
36510		 * DataTables, and you can add to this or modify it as you require.
36511		 *  @type function
36512		 *  @param {array} data Data array (array of objects which are name/value
36513		 *    pairs) that has been constructed by DataTables and will be sent to the
36514		 *    server. In the case of Ajax sourced data with server-side processing
36515		 *    this will be an empty array, for server-side processing there will be a
36516		 *    significant number of parameters!
36517		 *  @returns {undefined} Ensure that you modify the data array passed in,
36518		 *    as this is passed by reference.
36519		 *
36520		 *  @dtopt Callbacks
36521		 *  @dtopt Server-side
36522		 *  @name DataTable.defaults.serverParams
36523		 *
36524		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
36525		 */
36526		"fnServerParams": null,
36527
36528
36529		/**
36530		 * Load the table state. With this function you can define from where, and how, the
36531		 * state of a table is loaded. By default DataTables will load from `localStorage`
36532		 * but you might wish to use a server-side database or cookies.
36533		 *  @type function
36534		 *  @member
36535		 *  @param {object} settings DataTables settings object
36536		 *  @return {object} The DataTables state object to be loaded
36537		 *
36538		 *  @dtopt Callbacks
36539		 *  @name DataTable.defaults.stateLoadCallback
36540		 *
36541		 *  @example
36542		 *    $(document).ready( function() {
36543		 *      $('#example').dataTable( {
36544		 *        "stateSave": true,
36545		 *        "stateLoadCallback": function (settings) {
36546		 *          var o;
36547		 *
36548		 *          // Send an Ajax request to the server to get the data. Note that
36549		 *          // this is a synchronous request.
36550		 *          $.ajax( {
36551		 *            "url": "/state_load",
36552		 *            "async": false,
36553		 *            "dataType": "json",
36554		 *            "success": function (json) {
36555		 *              o = json;
36556		 *            }
36557		 *          } );
36558		 *
36559		 *          return o;
36560		 *        }
36561		 *      } );
36562		 *    } );
36563		 */
36564		"fnStateLoadCallback": function ( settings ) {
36565			try {
36566				return JSON.parse(
36567					(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
36568						'DataTables_'+settings.sInstance+'_'+location.pathname
36569					)
36570				);
36571			} catch (e) {}
36572		},
36573
36574
36575		/**
36576		 * Callback which allows modification of the saved state prior to loading that state.
36577		 * This callback is called when the table is loading state from the stored data, but
36578		 * prior to the settings object being modified by the saved state. Note that for
36579		 * plug-in authors, you should use the `stateLoadParams` event to load parameters for
36580		 * a plug-in.
36581		 *  @type function
36582		 *  @param {object} settings DataTables settings object
36583		 *  @param {object} data The state object that is to be loaded
36584		 *
36585		 *  @dtopt Callbacks
36586		 *  @name DataTable.defaults.stateLoadParams
36587		 *
36588		 *  @example
36589		 *    // Remove a saved filter, so filtering is never loaded
36590		 *    $(document).ready( function() {
36591		 *      $('#example').dataTable( {
36592		 *        "stateSave": true,
36593		 *        "stateLoadParams": function (settings, data) {
36594		 *          data.oSearch.sSearch = "";
36595		 *        }
36596		 *      } );
36597		 *    } );
36598		 *
36599		 *  @example
36600		 *    // Disallow state loading by returning false
36601		 *    $(document).ready( function() {
36602		 *      $('#example').dataTable( {
36603		 *        "stateSave": true,
36604		 *        "stateLoadParams": function (settings, data) {
36605		 *          return false;
36606		 *        }
36607		 *      } );
36608		 *    } );
36609		 */
36610		"fnStateLoadParams": null,
36611
36612
36613		/**
36614		 * Callback that is called when the state has been loaded from the state saving method
36615		 * and the DataTables settings object has been modified as a result of the loaded state.
36616		 *  @type function
36617		 *  @param {object} settings DataTables settings object
36618		 *  @param {object} data The state object that was loaded
36619		 *
36620		 *  @dtopt Callbacks
36621		 *  @name DataTable.defaults.stateLoaded
36622		 *
36623		 *  @example
36624		 *    // Show an alert with the filtering value that was saved
36625		 *    $(document).ready( function() {
36626		 *      $('#example').dataTable( {
36627		 *        "stateSave": true,
36628		 *        "stateLoaded": function (settings, data) {
36629		 *          alert( 'Saved filter was: '+data.oSearch.sSearch );
36630		 *        }
36631		 *      } );
36632		 *    } );
36633		 */
36634		"fnStateLoaded": null,
36635
36636
36637		/**
36638		 * Save the table state. This function allows you to define where and how the state
36639		 * information for the table is stored By default DataTables will use `localStorage`
36640		 * but you might wish to use a server-side database or cookies.
36641		 *  @type function
36642		 *  @member
36643		 *  @param {object} settings DataTables settings object
36644		 *  @param {object} data The state object to be saved
36645		 *
36646		 *  @dtopt Callbacks
36647		 *  @name DataTable.defaults.stateSaveCallback
36648		 *
36649		 *  @example
36650		 *    $(document).ready( function() {
36651		 *      $('#example').dataTable( {
36652		 *        "stateSave": true,
36653		 *        "stateSaveCallback": function (settings, data) {
36654		 *          // Send an Ajax request to the server with the state object
36655		 *          $.ajax( {
36656		 *            "url": "/state_save",
36657		 *            "data": data,
36658		 *            "dataType": "json",
36659		 *            "method": "POST"
36660		 *            "success": function () {}
36661		 *          } );
36662		 *        }
36663		 *      } );
36664		 *    } );
36665		 */
36666		"fnStateSaveCallback": function ( settings, data ) {
36667			try {
36668				(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
36669					'DataTables_'+settings.sInstance+'_'+location.pathname,
36670					JSON.stringify( data )
36671				);
36672			} catch (e) {}
36673		},
36674
36675
36676		/**
36677		 * Callback which allows modification of the state to be saved. Called when the table
36678		 * has changed state a new state save is required. This method allows modification of
36679		 * the state saving object prior to actually doing the save, including addition or
36680		 * other state properties or modification. Note that for plug-in authors, you should
36681		 * use the `stateSaveParams` event to save parameters for a plug-in.
36682		 *  @type function
36683		 *  @param {object} settings DataTables settings object
36684		 *  @param {object} data The state object to be saved
36685		 *
36686		 *  @dtopt Callbacks
36687		 *  @name DataTable.defaults.stateSaveParams
36688		 *
36689		 *  @example
36690		 *    // Remove a saved filter, so filtering is never saved
36691		 *    $(document).ready( function() {
36692		 *      $('#example').dataTable( {
36693		 *        "stateSave": true,
36694		 *        "stateSaveParams": function (settings, data) {
36695		 *          data.oSearch.sSearch = "";
36696		 *        }
36697		 *      } );
36698		 *    } );
36699		 */
36700		"fnStateSaveParams": null,
36701
36702
36703		/**
36704		 * Duration for which the saved state information is considered valid. After this period
36705		 * has elapsed the state will be returned to the default.
36706		 * Value is given in seconds.
36707		 *  @type int
36708		 *  @default 7200 <i>(2 hours)</i>
36709		 *
36710		 *  @dtopt Options
36711		 *  @name DataTable.defaults.stateDuration
36712		 *
36713		 *  @example
36714		 *    $(document).ready( function() {
36715		 *      $('#example').dataTable( {
36716		 *        "stateDuration": 60*60*24; // 1 day
36717		 *      } );
36718		 *    } )
36719		 */
36720		"iStateDuration": 7200,
36721
36722
36723		/**
36724		 * When enabled DataTables will not make a request to the server for the first
36725		 * page draw - rather it will use the data already on the page (no sorting etc
36726		 * will be applied to it), thus saving on an XHR at load time. `deferLoading`
36727		 * is used to indicate that deferred loading is required, but it is also used
36728		 * to tell DataTables how many records there are in the full table (allowing
36729		 * the information element and pagination to be displayed correctly). In the case
36730		 * where a filtering is applied to the table on initial load, this can be
36731		 * indicated by giving the parameter as an array, where the first element is
36732		 * the number of records available after filtering and the second element is the
36733		 * number of records without filtering (allowing the table information element
36734		 * to be shown correctly).
36735		 *  @type int | array
36736		 *  @default null
36737		 *
36738		 *  @dtopt Options
36739		 *  @name DataTable.defaults.deferLoading
36740		 *
36741		 *  @example
36742		 *    // 57 records available in the table, no filtering applied
36743		 *    $(document).ready( function() {
36744		 *      $('#example').dataTable( {
36745		 *        "serverSide": true,
36746		 *        "ajax": "scripts/server_processing.php",
36747		 *        "deferLoading": 57
36748		 *      } );
36749		 *    } );
36750		 *
36751		 *  @example
36752		 *    // 57 records after filtering, 100 without filtering (an initial filter applied)
36753		 *    $(document).ready( function() {
36754		 *      $('#example').dataTable( {
36755		 *        "serverSide": true,
36756		 *        "ajax": "scripts/server_processing.php",
36757		 *        "deferLoading": [ 57, 100 ],
36758		 *        "search": {
36759		 *          "search": "my_filter"
36760		 *        }
36761		 *      } );
36762		 *    } );
36763		 */
36764		"iDeferLoading": null,
36765
36766
36767		/**
36768		 * Number of rows to display on a single page when using pagination. If
36769		 * feature enabled (`lengthChange`) then the end user will be able to override
36770		 * this to a custom setting using a pop-up menu.
36771		 *  @type int
36772		 *  @default 10
36773		 *
36774		 *  @dtopt Options
36775		 *  @name DataTable.defaults.pageLength
36776		 *
36777		 *  @example
36778		 *    $(document).ready( function() {
36779		 *      $('#example').dataTable( {
36780		 *        "pageLength": 50
36781		 *      } );
36782		 *    } )
36783		 */
36784		"iDisplayLength": 10,
36785
36786
36787		/**
36788		 * Define the starting point for data display when using DataTables with
36789		 * pagination. Note that this parameter is the number of records, rather than
36790		 * the page number, so if you have 10 records per page and want to start on
36791		 * the third page, it should be "20".
36792		 *  @type int
36793		 *  @default 0
36794		 *
36795		 *  @dtopt Options
36796		 *  @name DataTable.defaults.displayStart
36797		 *
36798		 *  @example
36799		 *    $(document).ready( function() {
36800		 *      $('#example').dataTable( {
36801		 *        "displayStart": 20
36802		 *      } );
36803		 *    } )
36804		 */
36805		"iDisplayStart": 0,
36806
36807
36808		/**
36809		 * By default DataTables allows keyboard navigation of the table (sorting, paging,
36810		 * and filtering) by adding a `tabindex` attribute to the required elements. This
36811		 * allows you to tab through the controls and press the enter key to activate them.
36812		 * The tabindex is default 0, meaning that the tab follows the flow of the document.
36813		 * You can overrule this using this parameter if you wish. Use a value of -1 to
36814		 * disable built-in keyboard navigation.
36815		 *  @type int
36816		 *  @default 0
36817		 *
36818		 *  @dtopt Options
36819		 *  @name DataTable.defaults.tabIndex
36820		 *
36821		 *  @example
36822		 *    $(document).ready( function() {
36823		 *      $('#example').dataTable( {
36824		 *        "tabIndex": 1
36825		 *      } );
36826		 *    } );
36827		 */
36828		"iTabIndex": 0,
36829
36830
36831		/**
36832		 * Classes that DataTables assigns to the various components and features
36833		 * that it adds to the HTML table. This allows classes to be configured
36834		 * during initialisation in addition to through the static
36835		 * {@link DataTable.ext.oStdClasses} object).
36836		 *  @namespace
36837		 *  @name DataTable.defaults.classes
36838		 */
36839		"oClasses": {},
36840
36841
36842		/**
36843		 * All strings that DataTables uses in the user interface that it creates
36844		 * are defined in this object, allowing you to modified them individually or
36845		 * completely replace them all as required.
36846		 *  @namespace
36847		 *  @name DataTable.defaults.language
36848		 */
36849		"oLanguage": {
36850			/**
36851			 * Strings that are used for WAI-ARIA labels and controls only (these are not
36852			 * actually visible on the page, but will be read by screenreaders, and thus
36853			 * must be internationalised as well).
36854			 *  @namespace
36855			 *  @name DataTable.defaults.language.aria
36856			 */
36857			"oAria": {
36858				/**
36859				 * ARIA label that is added to the table headers when the column may be
36860				 * sorted ascending by activing the column (click or return when focu
36860sed).
36861				 * Note that the column header is prefixed to this string.
36862				 *  @type string
36863				 *  @default : activate to sort column ascending
36864				 *
36865				 *  @dtopt Language
36866				 *  @name DataTable.defaults.language.aria.sortAscending
36867				 *
36868				 *  @example
36869				 *    $(document).ready( function() {
36870				 *      $('#example').dataTable( {
36871				 *        "language": {
36872				 *          "aria": {
36873				 *            "sortAscending": " - click/return to sort ascending"
36874				 *          }
36875				 *        }
36876				 *      } );
36877				 *    } );
36878				 */
36879				"sSortAscending": ": activate to sort column ascending",
36880
36881				/**
36882				 * ARIA label that is added to the table headers when the column may be
36883				 * sorted descending by activing the column (click or return when focused).
36884				 * Note that the column header is prefixed to this string.
36885				 *  @type string
36886				 *  @default : activate to sort column ascending
36887				 *
36888				 *  @dtopt Language
36889				 *  @name DataTable.defaults.language.aria.sortDescending
36890				 *
36891				 *  @example
36892				 *    $(document).ready( function() {
36893				 *      $('#example').dataTable( {
36894				 *        "language": {
36895				 *          "aria": {
36896				 *            "sortDescending": " - click/return to sort descending"
36897				 *          }
36898				 *        }
36899				 *      } );
36900				 *    } );
36901				 */
36902				"sSortDescending": ": activate to sort column descending"
36903			},
36904
36905			/**
36906			 * Pagination string used by DataTables for the built-in pagination
36907			 * control types.
36908			 *  @namespace
36909			 *  @name DataTable.defaults.language.paginate
36910			 */
36911			"oPaginate": {
36912				/**
36913				 * Text to use when using the 'full_numbers' type of pagination for the
36914				 * button to take the user to the first page.
36915				 *  @type string
36916				 *  @default First
36917				 *
36918				 *  @dtopt Language
36919				 *  @name DataTable.defaults.language.paginate.first
36920				 *
36921				 *  @example
36922				 *    $(document).ready( function() {
36923				 *      $('#example').dataTable( {
36924				 *        "language": {
36925				 *          "paginate": {
36926				 *            "first": "First page"
36927				 *          }
36928				 *        }
36929				 *      } );
36930				 *    } );
36931				 */
36932				"sFirst": "First",
36933
36934
36935				/**
36936				 * Text to use when using the 'full_numbers' type of pagination for the
36937				 * button to take the user to the last page.
36938				 *  @type string
36939				 *  @default Last
36940				 *
36941				 *  @dtopt Language
36942				 *  @name DataTable.defaults.language.paginate.last
36943				 *
36944				 *  @example
36945				 *    $(document).ready( function() {
36946				 *      $('#example').dataTable( {
36947				 *        "language": {
36948				 *          "paginate": {
36949				 *            "last": "Last page"
36950				 *          }
36951				 *        }
36952				 *      } );
36953				 *    } );
36954				 */
36955				"sLast": "Last",
36956
36957
36958				/**
36959				 * Text to use for the 'next' pagination button (to take the user to the
36960				 * next page).
36961				 *  @type string
36962				 *  @default Next
36963				 *
36964				 *  @dtopt Language
36965				 *  @name DataTable.defaults.language.paginate.next
36966				 *
36967				 *  @example
36968				 *    $(document).ready( function() {
36969				 *      $('#example').dataTable( {
36970				 *        "language": {
36971				 *          "paginate": {
36972				 *            "next": "Next page"
36973				 *          }
36974				 *        }
36975				 *      } );
36976				 *    } );
36977				 */
36978				"sNext": "Next",
36979
36980
36981				/**
36982				 * Text to use for the 'previous' pagination button (to take the user to
36983				 * the previous page).
36984				 *  @type string
36985				 *  @default Previous
36986				 *
36987				 *  @dtopt Language
36988				 *  @name DataTable.defaults.language.paginate.previous
36989				 *
36990				 *  @example
36991				 *    $(document).ready( function() {
36992				 *      $('#example').dataTable( {
36993				 *        "language": {
36994				 *          "paginate": {
36995				 *            "previous": "Previous page"
36996				 *          }
36997				 *        }
36998				 *      } );
36999				 *    } );
37000				 */
37001				"sPrevious": "Previous"
37002			},
37003
37004			/**
37005			 * This string is shown in preference to `zeroRecords` when the table is
37006			 * empty of data (regardless of filtering). Note that this is an optional
37007			 * parameter - if it is not given, the value of `zeroRecords` will be used
37008			 * instead (either the default or given value).
37009			 *  @type string
37010			 *  @default No data available in table
37011			 *
37012			 *  @dtopt Language
37013			 *  @name DataTable.defaults.language.emptyTable
37014			 *
37015			 *  @example
37016			 *    $(document).ready( function() {
37017			 *      $('#example').dataTable( {
37018			 *        "language": {
37019			 *          "emptyTable": "No data available in table"
37020			 *        }
37021			 *      } );
37022			 *    } );
37023			 */
37024			"sEmptyTable": "No data available in table",
37025
37026
37027			/**
37028			 * This string gives information to the end user about the information
37029			 * that is current on display on the page. The following tokens can be
37030			 * used in the string and will be dynamically replaced as the table
37031			 * display updates. This tokens can be placed anywhere in the string, or
37032			 * removed as needed by the language requires:
37033			 *
37034			 * * `\_START\_` - Display index of the first record on the current page
37035			 * * `\_END\_` - Display index of the last record on the current page
37036			 * * `\_TOTAL\_` - Number of records in the table after filtering
37037			 * * `\_MAX\_` - Number of records in the table without filtering
37038			 * * `\_PAGE\_` - Current page number
37039			 * * `\_PAGES\_` - Total number of pages of data in the table
37040			 *
37041			 *  @type string
37042			 *  @default Showing _START_ to _END_ of _TOTAL_ entries
37043			 *
37044			 *  @dtopt Language
37045			 *  @name DataTable.defaults.language.info
37046			 *
37047			 *  @example
37048			 *    $(document).ready( function() {
37049			 *      $('#example').dataTable( {
37050			 *        "language": {
37051			 *          "info": "Showing page _PAGE_ of _PAGES_"
37052			 *        }
37053			 *      } );
37054			 *    } );
37055			 */
37056			"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
37057
37058
37059			/**
37060			 * Display information string for when the table is empty. Typically the
37061			 * format of this string should match `info`.
37062			 *  @type string
37063			 *  @default Showing 0 to 0 of 0 entries
37064			 *
37065			 *  @dtopt Language
37066			 *  @name DataTable.defaults.language.infoEmpty
37067			 *
37068			 *  @example
37069			 *    $(document).ready( function() {
37070			 *      $('#example').dataTable( {
37071			 *        "language": {
37072			 *          "infoEmpty": "No entries to show"
37073			 *        }
37074			 *      } );
37075			 *    } );
37076			 */
37077			"sInfoEmpty": "Showing 0 to 0 of 0 entries",
37078
37079
37080			/**
37081			 * When a user filters the information in a table, this string is appended
37082			 * to the information (`info`) to give an idea of how strong the filtering
37083			 * is. The variable _MAX_ is dynamically updated.
37084			 *  @type string
37085			 *  @default (filtered from _MAX_ total entries)
37086			 *
37087			 *  @dtopt Language
37088			 *  @name DataTable.defaults.language.infoFiltered
37089			 *
37090			 *  @example
37091			 *    $(document).ready( function() {
37092			 *      $('#example').dataTable( {
37093			 *        "language": {
37094			 *          "infoFiltered": " - filtering from _MAX_ records"
37095			 *        }
37096			 *      } );
37097			 *    } );
37098			 */
37099			"sInfoFiltered": "(filtered from _MAX_ total entries)",
37100
37101
37102			/**
37103			 * If can be useful to append extra information to the info string at times,
37104			 * and this variable does exactly that. This information will be appended to
37105			 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
37106			 * being used) at all times.
37107			 *  @type string
37108			 *  @default <i>Empty string</i>
37109			 *
37110			 *  @dtopt Language
37111			 *  @name DataTable.defaults.language.infoPostFix
37112			 *
37113			 *  @example
37114			 *    $(document).ready( function() {
37115			 *      $('#example').dataTable( {
37116			 *        "language": {
37117			 *          "infoPostFix": "All records shown are derived from real information."
37118			 *        }
37119			 *      } );
37120			 *    } );
37121			 */
37122			"sInfoPostFix": "",
37123
37124
37125			/**
37126			 * This decimal place operator is a little different from the other
37127			 * language options since DataTables doesn't output floating point
37128			 * numbers, so it won't ever use this for display of a number. Rather,
37129			 * what this parameter does is modify the sort methods of the table so
37130			 * that numbers which are in a format which has a character other than
37131			 * a period (`.`) as a decimal place will be sorted numerically.
37132			 *
37133			 * Note that numbers with different decimal places cannot be shown in
37134			 * the same table and still be sortable, the table must be consistent.
37135			 * However, multiple different tables on the page can use different
37136			 * decimal place characters.
37137			 *  @type string
37138			 *  @default
37139			 *
37140			 *  @dtopt Language
37141			 *  @name DataTable.defaults.language.decimal
37142			 *
37143			 *  @example
37144			 *    $(document).ready( function() {
37145			 *      $('#example').dataTable( {
37146			 *        "language": {
37147			 *          "decimal": ","
37148			 *          "thousands": "."
37149			 *        }
37150			 *      } );
37151			 *    } );
37152			 */
37153			"sDecimal": "",
37154
37155
37156			/**
37157			 * DataTables has a build in number formatter (`formatNumber`) which is
37158			 * used to format large numbers that are used in the table information.
37159			 * By default a comma is used, but this can be trivially changed to any
37160			 * character you wish with this parameter.
37161			 *  @type string
37162			 *  @default ,
37163			 *
37164			 *  @dtopt Language
37165			 *  @name DataTable.defaults.language.thousands
37166			 *
37167			 *  @example
37168			 *    $(document).ready( function() {
37169			 *      $('#example').dataTable( {
37170			 *        "language": {
37171			 *          "thousands": "'"
37172			 *        }
37173			 *      } );
37174			 *    } );
37175			 */
37176			"sThousands": ",",
37177
37178
37179			/**
37180			 * Detail the action that will be taken when the drop down menu for the
37181			 * pagination length option is changed. The '_MENU_' variable is replaced
37182			 * with a default select list of 10, 25, 50 and 100, and can be replaced
37183			 * with a custom select box if required.
37184			 *  @type string
37185			 *  @default Show _MENU_ entries
37186			 *
37187			 *  @dtopt Language
37188			 *  @name DataTable.defaults.language.lengthMenu
37189			 *
37190			 *  @example
37191			 *    // Language change only
37192			 *    $(document).ready( function() {
37193			 *      $('#example').dataTable( {
37194			 *        "language": {
37195			 *          "lengthMenu": "Display _MENU_ records"
37196			 *        }
37197			 *      } );
37198			 *    } );
37199			 *
37200			 *  @example
37201			 *    // Language and options change
37202			 *    $(document).ready( function() {
37203			 *      $('#example').dataTable( {
37204			 *        "language": {
37205			 *          "lengthMenu": 'Display <select>'+
37206			 *            '<option value="10">10</option>'+
37207			 *            '<option value="20">20</option>'+
37208			 *            '<option value="30">30</option>'+
37209			 *            '<option value="40">40</option>'+
37210			 *            '<option value="50">50</option>'+
37211			 *            '<option value="-1">All</option>'+
37212			 *            '</select> records'
37213			 *        }
37214			 *      } );
37215			 *    } );
37216			 */
37217			"sLengthMenu": "Show _MENU_ entries",
37218
37219
37220			/**
37221			 * When using Ajax sourced data and during the first draw when DataTables is
37222			 * gathering the data, this message is shown in an empty row in the table to
37223			 * indicate to the end user the the data is being loaded. Note that this
37224			 * parameter is not used when loading data by server-side processing, just
37225			 * Ajax sourced data with client-side processing.
37226			 *  @type string
37227			 *  @default Loading...
37228			 *
37229			 *  @dtopt Language
37230			 *  @name DataTable.defaults.language.loadingRecords
37231			 *
37232			 *  @example
37233			 *    $(document).ready( function() {
37234			 *      $('#example').dataTable( {
37235			 *        "language": {
37236			 *          "loadingRecords": "Please wait - loading..."
37237			 *        }
37238			 *      } );
37239			 *    } );
37240			 */
37241			"sLoadingRecords": "Loading...",
37242
37243
37244			/**
37245			 * Text which is displayed when the table is processing a user action
37246			 * (usually a sort command or similar).
37247			 *  @type string
37248			 *  @default Processing...
37249			 *
37250			 *  @dtopt Language
37251			 *  @name DataTable.defaults.language.processing
37252			 *
37253			 *  @example
37254			 *    $(document).ready( function() {
37255			 *      $('#example').dataTable( {
37256			 *        "language": {
37257			 *          "processing": "DataTables is currently busy"
37258			 *        }
37259			 *      } );
37260			 *    } );
37261			 */
37262			"sProcessing": "Processing...",
37263
37264
37265			/**
37266			 * Details the actions that will be taken when the user types into the
37267			 * filtering input text box. The variable "_INPUT_", if used in the string,
37268			 * is replaced with the HTML text box for the filtering input allowing
37269			 * control over where it appears in the string. If "_INPUT_" is not given
37270			 * then the input box is appended to the string automatically.
37271			 *  @type string
37272			 *  @default Search:
37273			 *
37274			 *  @dtopt Language
37275			 *  @name DataTable.defaults.language.search
37276			 *
37277			 *  @example
37278			 *    // Input text box will be appended at the end automatically
37279			 *    $(document).ready( function() {
37280			 *      $('#example').dataTable( {
37281			 *        "language": {
37282			 *          "search": "Filter records:"
37283			 *        }
37284			 *      } );
37285			 *    } );
37286			 *
37287			 *  @example
37288			 *    // Specify where the filter should appear
37289			 *    $(document).ready( function() {
37290			 *      $('#example').dataTable( {
37291			 *        "language": {
37292			 *          "search": "Apply filter _INPUT_ to table"
37293			 *        }
37294			 *      } );
37295			 *    } );
37296			 */
37297			"sSearch": "Search:",
37298
37299
37300			/**
37301			 * Assign a `placeholder` attribute to the search `input` element
37302			 *  @type string
37303			 *  @default
37304			 *
37305			 *  @dtopt Language
37306			 *  @name DataTable.defaults.language.searchPlaceholder
37307			 */
37308			"sSearchPlaceholder": "",
37309
37310
37311			/**
37312			 * All of the language information can be stored in a file on the
37313			 * server-side, which DataTables will look up if this parameter is passed.
37314			 * It must store the URL of the language file, which is in a JSON format,
37315			 * and the object has the same properties as the oLanguage object in the
37316			 * initialiser object (i.e. the above parameters). Please refer to one of
37317			 * the example language files to see how this works in action.
37318			 *  @type string
37319			 *  @default <i>Empty string - i.e. disabled</i>
37320			 *
37321			 *  @dtopt Language
37322			 *  @name DataTable.defaults.language.url
37323			 *
37324			 *  @example
37325			 *    $(document).ready( function() {
37326			 *      $('#example').dataTable( {
37327			 *        "language": {
37328			 *          "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
37329			 *        }
37330			 *      } );
37331			 *    } );
37332			 */
37333			"sUrl": "",
37334
37335
37336			/**
37337			 * Text shown inside the table records when the is no information to be
37338			 * displayed after filtering. `emptyTable` is shown when there is simply no
37339			 * information in the table at all (regardless of filtering).
37340			 *  @type string
37341			 *  @default No matching records found
37342			 *
37343			 *  @dtopt Language
37344			 *  @name DataTable.defaults.language.zeroRecords
37345			 *
37346			 *  @example
37347			 *    $(document).ready( function() {
37348			 *      $('#example').dataTable( {
37349			 *        "language": {
37350			 *          "zeroRecords": "No records to display"
37351			 *        }
37352			 *      } );
37353			 *    } );
37354			 */
37355			"sZeroRecords": "No matching records found"
37356		},
37357
37358
37359		/**
37360		 * This parameter allows you to have define the global filtering state at
37361		 * initialisation time. As an object the `search` parameter must be
37362		 * defined, but all other parameters are optional. When `regex` is true,
37363		 * the search string will be treated as a regular expression, when false
37364		 * (default) it will be treated as a straight string. When `smart`
37365		 * DataTables will use it's smart filtering methods (to word match at
37366		 * any point in the data), when false this will not be done.
37367		 *  @namespace
37368		 *  @extends DataTable.models.oSearch
37369		 *
37370		 *  @dtopt Options
37371		 *  @name DataTable.defaults.search
37372		 *
37373		 *  @example
37374		 *    $(document).ready( function() {
37375		 *      $('#example').dataTable( {
37376		 *        "search": {"search": "Initial search"}
37377		 *      } );
37378		 *    } )
37379		 */
37380		"oSearch": $.extend( {}, DataTable.models.oSearch ),
37381
37382
37383		/**
37384		 * __Deprecated__ The functionality provided by this parameter has now been
37385		 * superseded by that provided through `ajax`, which should be used instead.
37386		 *
37387		 * By default DataTables will look for the property `data` (or `aaData` for
37388		 * compatibility with DataTables 1.9-) when obtaining data from an Ajax
37389		 * source or for server-side processing - this parameter allows that
37390		 * property to be changed. You can use Javascript dotted object notation to
37391		 * get a data source for multiple levels of nesting.
37392		 *  @type string
37393		 *  @default data
37394		 *
37395		 *  @dtopt Options
37396		 *  @dtopt Server-side
37397		 *  @name DataTable.defaults.ajaxDataProp
37398		 *
37399		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
37400		 */
37401		"sAjaxDataProp": "data",
37402
37403
37404		/**
37405		 * __Deprecated__ The functionality provided by this parameter has now been
37406		 * superseded by that provided through `ajax`, which should be used instead.
37407		 *
37408		 * You can instruct DataTables to load data from an external
37409		 * source using this parameter (use aData if you want to pass data in you
37410		 * already have). Simply provide a url a JSON object can be obtained from.
37411		 *  @type string
37412		 *  @default null
37413		 *
37414		 *  @dtopt Options
37415		 *  @dtopt Server-side
37416		 *  @name DataTable.defaults.ajaxSource
37417		 *
37418		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
37419		 */
37420		"sAjaxSource": null,
37421
37422
37423		/**
37424		 * This initialisation variable allows you to specify exactly where in the
37425		 * DOM you want DataTables to inject the various controls it adds to the page
37426		 * (for example you might want the pagination controls at the top of the
37427		 * table). DIV elements (with or without a custom class) can also be added to
37428		 * aid styling. The follow syntax is used:
37429		 *   <ul>
37430		 *     <li>The following options are allowed:
37431		 *       <ul>
37432		 *         <li>'l' - Length changing</li>
37433		 *         <li>'f' - Filtering input</li>
37434		 *         <li>'t' - The table!</li>
37435		 *         <li>'i' - Information</li>
37436		 *         <li>'p' - Pagination</li>
37437		 *         <li>'r' - pRocessing</li>
37438		 *       </ul>
37439		 *     </li>
37440		 *     <li>The following constants are allowed:
37441		 *       <ul>
37442		 *         <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
37443		 *         <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
37444		 *       </ul>
37445		 *     </li>
37446		 *     <li>The following syntax is expected:
37447		 *       <ul>
37448		 *         <li>'&lt;' and '&gt;' - div elements</li>
37449		 *         <li>'&lt;"class" and '&gt;' - div with a class</li>
37450		 *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
37451		 *       </ul>
37452		 *     </li>
37453		 *     <li>Examples:
37454		 *       <ul>
37455		 *         <li>'&lt;"wrapper"flipt&gt;'</li>
37456		 *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
37457		 *       </ul>
37458		 *     </li>
37459		 *   </ul>
37460		 *  @type string
37461		 *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
37462		 *    <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
37463		 *
37464		 *  @dtopt Options
37465		 *  @name DataTable.defaults.dom
37466		 *
37467		 *  @example
37468		 *    $(document).ready( function() {
37469		 *      $('#example').dataTable( {
37470		 *        "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
37471		 *      } );
37472		 *    } );
37473		 */
37474		"sDom": "lfrtip",
37475
37476
37477		/**
37478		 * Search delay option. This will throttle full table searches that use the
37479		 * DataTables provided search input element (it does not effect calls to
37480		 * `dt-api search()`, providing a delay before the search is made.
37481		 *  @type integer
37482		 *  @default 0
37483		 *
37484		 *  @dtopt Options
37485		 *  @name DataTable.defaults.searchDelay
37486		 *
37487		 *  @example
37488		 *    $(document).ready( function() {
37489		 *      $('#example').dataTable( {
37490		 *        "searchDelay": 200
37491		 *      } );
37492		 *    } )
37493		 */
37494		"searchDelay": null,
37495
37496
37497		/**
37498		 * DataTables features four different built-in options for the buttons to
37499		 * display for pagination control:
37500		 *
37501		 * * `simple` - 'Previous' and 'Next' buttons only
37502		 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
37503		 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
37504		 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
37505		 *   page numbers
37506		 *
37507		 * Further methods can be added using {@link DataTable.ext.oPagination}.
37508		 *  @type string
37509		 *  @default simple_numbers
37510		 *
37511		 *  @dtopt Options
37512		 *  @name DataTable.defaults.pagingType
37513		 *
37514		 *  @example
37515		 *    $(document).ready( function() {
37516		 *      $('#example').dataTable( {
37517		 *        "pagingType": "full_numbers"
37518		 *      } );
37519		 *    } )
37520		 */
37521		"sPaginationType": "simple_numbers",
37522
37523
37524		/**
37525		 * Enable horizontal scrolling. When a table is too wide to fit into a
37526		 * certain layout, or you have a large number of columns in the table, you
37527		 * can enable x-scrolling to show the table in a viewport, which can be
37528		 * scrolled. This property can be `true` which will allow the table to
37529		 * scroll horizontally when needed, or any CSS unit, or a number (in which
37530		 * case it will be treated as a pixel measurement). Setting as simply `true`
37531		 * is recommended.
37532		 *  @type boolean|string
37533		 *  @default <i>blank string - i.e. disabled</i>
37534		 *
37535		 *  @dtopt Features
37536		 *  @name DataTable.defaults.scrollX
37537		 *
37538		 *  @example
37539		 *    $(document).ready( function() {
37540		 *      $('#example').dataTable( {
37541		 *        "scrollX": true,
37542		 *        "scrollCollapse": true
37543		 *      } );
37544		 *    } );
37545		 */
37546		"sScrollX": "",
37547
37548
37549		/**
37550		 * This property can be used to force a DataTable to use more width than it
37551		 * might otherwise do when x-scrolling is enabled. For example if you have a
37552		 * table which requires to be well spaced, this parameter is useful for
37553		 * "over-sizing" the table, and thus forcing scrolling. This property can by
37554		 * any CSS unit, or a number (in which case it will be treated as a pixel
37555		 * measurement).
37556		 *  @type string
37557		 *  @default <i>blank string - i.e. disabled</i>
37558		 *
37559		 *  @dtopt Options
37560		 *  @name DataTable.defaults.scrollXInner
37561		 *
37562		 *  @example
37563		 *    $(document).ready( function() {
37564		 *      $('#example').dataTable( {
37565		 *        "scrollX": "100%",
37566		 *        "scrollXInner": "110%"
37567		 *      } );
37568		 *    } );
37569		 */
37570		"sScrollXInner": "",
37571
37572
37573		/**
37574		 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
37575		 * to the given height, and enable scrolling for any data which overflows the
37576		 * current viewport. This can be used as an alternative to paging to display
37577		 * a lot of data in a small area (although paging and scrolling can both be
37578		 * enabled at the same time). This property can be any CSS unit, or a number
37579		 * (in which case it will be treated as a pixel measurement).
37580		 *  @type string
37581		 *  @default <i>blank string - i.e. disabled</i>
37582		 *
37583		 *  @dtopt Features
37584		 *  @name DataTable.defaults.scrollY
37585		 *
37586		 *  @example
37587		 *    $(document).ready( function() {
37588		 *      $('#example').dataTable( {
37589		 *        "scrollY": "200px",
37590		 *        "paginate": false
37591		 *      } );
37592		 *    } );
37593		 */
37594		"sScrollY": "",
37595
37596
37597		/**
37598		 * __Deprecated__ The functionality provided by this parameter has now been
37599		 * superseded by that provided through `ajax`, which should be used instead.
37600		 *
37601		 * Set the HTTP method that is used to make the Ajax call for server-side
37602		 * processing or Ajax sourced data.
37603		 *  @type string
37604		 *  @default GET
37605		 *
37606		 *  @dtopt Options
37607		 *  @dtopt Server-side
37608		 *  @name DataTable.defaults.serverMethod
37609		 *
37610		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
37611		 */
37612		"sServerMethod": "GET",
37613
37614
37615		/**
37616		 * DataTables makes use of renderers when displaying HTML elements for
37617		 * a table. These renderers can be added or modified by plug-ins to
37618		 * generate suitable mark-up for a site. For example the Bootstrap
37619		 * integration plug-in for DataTables uses a paging button renderer to
37620		 * display pagination buttons in the mark-up required by Bootstrap.
37621		 *
37622		 * For further information about the renderers available see
37623		 * DataTable.ext.renderer
37624		 *  @type string|object
37625		 *  @default null
37626		 *
37627		 *  @name DataTable.defaults.renderer
37628		 *
37629		 */
37630		"renderer": null,
37631
37632
37633		/**
37634		 * Set the data property name that DataTables should use to get a row's id
37635		 * to set as the `id` property in the node.
37636		 *  @type string
37637		 *  @default DT_RowId
37638		 *
37639		 *  @name DataTable.defaults.rowId
37640		 */
37641		"rowId": "DT_RowId"
37642	};
37643
37644	_fnHungarianMap( DataTable.defaults );
37645
37646
37647
37648	/*
37649	 * Developer note - See note in model.defaults.js about the use of Hungarian
37650	 * notation and camel case.
37651	 */
37652
37653	/**
37654	 * Column options that can be given to DataTables at initialisation time.
37655	 *  @namespace
37656	 */
37657	DataTable.defaults.column = {
37658		/**
37659		 * Define which column(s) an order will occur on for this column. This
37660		 * allows a column's ordering to take multiple columns into account when
37661		 * doing a sort or use the data from a different column. For example first
37662		 * name / last name columns make sense to do a multi-column sort over the
37663		 * two columns.
37664		 *  @type array|int
37665		 *  @default null <i>Takes the value of the column index automatically</i>
37666		 *
37667		 *  @name DataTable.defaults.column.orderData
37668		 *  @dtopt Columns
37669		 *
37670		 *  @example
37671		 *    // Using `columnDefs`
37672		 *    $(document).ready( function() {
37673		 *      $('#example').dataTable( {
37674		 *        "columnDefs": [
37675		 *          { "orderData": [ 0, 1 ], "targets": [ 0 ] },
37676		 *          { "orderData": [ 1, 0 ], "targets": [ 1 ] },
37677		 *          { "orderData": 2, "targets": [ 2 ] }
37678		 *        ]
37679		 *      } );
37680		 *    } );
37681		 *
37682		 *  @example
37683		 *    // Using `columns`
37684		 *    $(document).ready( function() {
37685		 *      $('#example').dataTable( {
37686		 *        "columns": [
37687		 *          { "orderData": [ 0, 1 ] },
37688		 *          { "orderData": [ 1, 0 ] },
37689		 *          { "orderData": 2 },
37690		 *          null,
37691		 *          null
37692		 *        ]
37693		 *      } );
37694		 *    } );
37695		 */
37696		"aDataSort": null,
37697		"iDataSort": -1,
37698
37699
37700		/**
37701		 * You can control the default ordering direction, and even alter the
37702		 * behaviour of the sort handler (i.e. only allow ascending ordering etc)
37703		 * using this parameter.
37704		 *  @type array
37705		 *  @default [ 'asc', 'desc' ]
37706		 *
37707		 *  @name DataTable.defaults.column.orderSequence
37708		 *  @dtopt Columns
37709		 *
37710		 *  @example
37711		 *    // Using `columnDefs`
37712		 *    $(document).ready( function() {
37713		 *      $('#example').dataTable( {
37714		 *        "columnDefs": [
37715		 *          { "orderSequence": [ "asc" ], "targets": [ 1 ] },
37716		 *          { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
37717		 *          { "orderSequence": [ "desc" ], "targets": [ 3 ] }
37718		 *        ]
37719		 *      } );
37720		 *    } );
37721		 *
37722		 *  @example
37723		 *    // Using `columns`
37724		 *    $(document).ready( function() {
37725		 *      $('#example').dataTable( {
37726		 *        "columns": [
37727		 *          null,
37728		 *          { "orderSequence": [ "asc" ] },
37729		 *          { "orderSequence": [ "desc", "asc", "asc" ] },
37730		 *          { "orderSequence": [ "desc" ] },
37731		 *          null
37732		 *        ]
37733		 *      } );
37734		 *    } );
37735		 */
37736		"asSorting": [ 'asc', 'desc' ],
37737
37738
37739		/**
37740		 * Enable or disable filtering on the data in this column.
37741		 *  @type boolean
37742		 *  @default true
37743		 *
37744		 *  @name DataTable.defaults.column.searchable
37745		 *  @dtopt Columns
37746		 *
37747		 *  @example
37748		 *    // Using `columnDefs`
37749		 *    $(document).ready( function() {
37750		 *      $('#example').dataTable( {
37751		 *        "columnDefs": [
37752		 *          { "searchable": false, "targets": [ 0 ] }
37753		 *        ] } );
37754		 *    } );
37755		 *
37756		 *  @example
37757		 *    // Using `columns`
37758		 *    $(document).ready( function() {
37759		 *      $('#example').dataTable( {
37760		 *        "columns": [
37761		 *          { "searchable": false },
37762		 *          null,
37763		 *          null,
37764		 *          null,
37765		 *          null
37766		 *        ] } );
37767		 *    } );
37768		 */
37769		"bSearchable": true,
37770
37771
37772		/**
37773		 * Enable or disable ordering on this column.
37774		 *  @type boolean
37775		 *  @default true
37776		 *
37777		 *  @name DataTable.defaults.column.orderable
37778		 *  @dtopt Columns
37779		 *
37780		 *  @example
37781		 *    // Using `columnDefs`
37782		 *    $(document).ready( function() {
37783		 *      $('#example').dataTable( {
37784		 *        "columnDefs": [
37785		 *          { "orderable": false, "targets": [ 0 ] }
37786		 *        ] } );
37787		 *    } );
37788		 *
37789		 *  @example
37790		 *    // Using `columns`
37791		 *    $(document).ready( function() {
37792		 *      $('#example').dataTable( {
37793		 *        "columns": [
37794		 *          { "orderable": false },
37795		 *          null,
37796		 *          null,
37797		 *          null,
37798		 *          null
37799		 *        ] } );
37800		 *    } );
37801		 */
37802		"bSortable": true,
37803
37804
37805		/**
37806		 * Enable or disable the display of this column.
37807		 *  @type boolean
37808		 *  @default true
37809		 *
37810		 *  @name DataTable.defaults.column.visible
37811		 *  @dtopt Columns
37812		 *
37813		 *  @example
37814		 *    // Using `columnDefs`
37815		 *    $(document).ready( function() {
37816		 *      $('#example').dataTable( {
37817		 *        "columnDefs": [
37818		 *          { "visible": false, "targets": [ 0 ] }
37819		 *        ] } );
37820		 *    } );
37821		 *
37822		 *  @example
37823		 *    // Using `columns`
37824		 *    $(document).ready( function() {
37825		 *      $('#example').dataTable( {
37826		 *        "columns": [
37827		 *          { "visible": false },
37828		 *          null,
37829		 *          null,
37830		 *          null,
37831		 *          null
37832		 *        ] } );
37833		 *    } );
37834		 */
37835		"bVisible": true,
37836
37837
37838		/**
37839		 * Developer definable function that is called whenever a cell is created (Ajax source,
37840		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
37841		 * allowing you to modify the DOM element (add background colour for example) when the
37842		 * element is available.
37843		 *  @type function
37844		 *  @param {element} td The TD node that has been created
37845		 *  @param {*} cellData The Data for the cell
37846		 *  @param {array|object} rowData The data for the whole row
37847		 *  @param {int} row The row index for the aoData data store
37848		 *  @param {int} col The column index for aoColumns
37849		 *
37850		 *  @name DataTable.defaults.column.createdCell
37851		 *  @dtopt Columns
37852		 *
37853		 *  @example
37854		 *    $(document).ready( function() {
37855		 *      $('#example').dataTable( {
37856		 *        "columnDefs": [ {
37857		 *          "targets": [3],
37858		 *          "createdCell": function (td, cellData, rowData, row, c
37858ol) {
37859		 *            if ( cellData == "1.7" ) {
37860		 *              $(td).css('color', 'blue')
37861		 *            }
37862		 *          }
37863		 *        } ]
37864		 *      });
37865		 *    } );
37866		 */
37867		"fnCreatedCell": null,
37868
37869
37870		/**
37871		 * This parameter has been replaced by `data` in DataTables to ensure naming
37872		 * consistency. `dataProp` can still be used, as there is backwards
37873		 * compatibility in DataTables for this option, but it is strongly
37874		 * recommended that you use `data` in preference to `dataProp`.
37875		 *  @name DataTable.defaults.column.dataProp
37876		 */
37877
37878
37879		/**
37880		 * This property can be used to read data from any data source property,
37881		 * including deeply nested objects / properties. `data` can be given in a
37882		 * number of different ways which effect its behaviour:
37883		 *
37884		 * * `integer` - treated as an array index for the data source. This is the
37885		 *   default that DataTables uses (incrementally increased for each column).
37886		 * * `string` - read an object property from the data source. There are
37887		 *   three 'special' options that can be used in the string to alter how
37888		 *   DataTables reads the data from the source object:
37889		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
37890		 *      Javascript to read from nested objects, so to can the options
37891		 *      specified in `data`. For example: `browser.version` or
37892		 *      `browser.name`. If your object parameter name contains a period, use
37893		 *      `\\` to escape it - i.e. `first\\.name`.
37894		 *    * `[]` - Array notation. DataTables can automatically combine data
37895		 *      from and array source, joining the data with the characters provided
37896		 *      between the two brackets. For example: `name[, ]` would provide a
37897		 *      comma-space separated list from the source array. If no characters
37898		 *      are provided between the brackets, the original array source is
37899		 *      returned.
37900		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
37901		 *      execute a function of the name given. For example: `browser()` for a
37902		 *      simple function on the data source, `browser.version()` for a
37903		 *      function in a nested property or even `browser().version` to get an
37904		 *      object property if the function called returns an object. Note that
37905		 *      function notation is recommended for use in `render` rather than
37906		 *      `data` as it is much simpler to use as a renderer.
37907		 * * `null` - use the original data source for the row rather than plucking
37908		 *   data directly from it. This action has effects on two other
37909		 *   initialisation options:
37910		 *    * `defaultContent` - When null is given as the `data` option and
37911		 *      `defaultContent` is specified for the column, the value defined by
37912		 *      `defaultContent` will be used for the cell.
37913		 *    * `render` - When null is used for the `data` option and the `render`
37914		 *      option is specified for the column, the whole data source for the
37915		 *      row is used for the renderer.
37916		 * * `function` - the function given will be executed whenever DataTables
37917		 *   needs to set or get the data for a cell in the column. The function
37918		 *   takes three parameters:
37919		 *    * Parameters:
37920		 *      * `{array|object}` The data source for the row
37921		 *      * `{string}` The type call data requested - this will be 'set' when
37922		 *        setting data or 'filter', 'display', 'type', 'sort' or undefined
37923		 *        when gathering data. Note that when `undefined` is given for the
37924		 *        type DataTables expects to get the raw data for the object back<
37925		 *      * `{*}` Data to set when the second parameter is 'set'.
37926		 *    * Return:
37927		 *      * The return value from the function is not required when 'set' is
37928		 *        the type of call, but otherwise the return is what will be used
37929		 *        for the data requested.
37930		 *
37931		 * Note that `data` is a getter and setter option. If you just require
37932		 * formatting of data for output, you will likely want to use `render` which
37933		 * is simply a getter and thus simpler to use.
37934		 *
37935		 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
37936		 * name change reflects the flexibility of this property and is consistent
37937		 * with the naming of mRender. If 'mDataProp' is given, then it will still
37938		 * be used by DataTables, as it automatically maps the old name to the new
37939		 * if required.
37940		 *
37941		 *  @type string|int|function|null
37942		 *  @default null <i>Use automatically calculated column index</i>
37943		 *
37944		 *  @name DataTable.defaults.column.data
37945		 *  @dtopt Columns
37946		 *
37947		 *  @example
37948		 *    // Read table data from objects
37949		 *    // JSON structure for each row:
37950		 *    //   {
37951		 *    //      "engine": {value},
37952		 *    //      "browser": {value},
37953		 *    //      "platform": {value},
37954		 *    //      "version": {value},
37955		 *    //      "grade": {value}
37956		 *    //   }
37957		 *    $(document).ready( function() {
37958		 *      $('#example').dataTable( {
37959		 *        "ajaxSource": "sources/objects.txt",
37960		 *        "columns": [
37961		 *          { "data": "engine" },
37962		 *          { "data": "browser" },
37963		 *          { "data": "platform" },
37964		 *          { "data": "version" },
37965		 *          { "data": "grade" }
37966		 *        ]
37967		 *      } );
37968		 *    } );
37969		 *
37970		 *  @example
37971		 *    // Read information from deeply nested objects
37972		 *    // JSON structure for each row:
37973		 *    //   {
37974		 *    //      "engine": {value},
37975		 *    //      "browser": {value},
37976		 *    //      "platform": {
37977		 *    //         "inner": {value}
37978		 *    //      },
37979		 *    //      "details": [
37980		 *    //         {value}, {value}
37981		 *    //      ]
37982		 *    //   }
37983		 *    $(document).ready( function() {
37984		 *      $('#example').dataTable( {
37985		 *        "ajaxSource": "sources/deep.txt",
37986		 *        "columns": [
37987		 *          { "data": "engine" },
37988		 *          { "data": "browser" },
37989		 *          { "data": "platform.inner" },
37990		 *          { "data": "platform.details.0" },
37991		 *          { "data": "platform.details.1" }
37992		 *        ]
37993		 *      } );
37994		 *    } );
37995		 *
37996		 *  @example
37997		 *    // Using `data` as a function to provide different information for
37998		 *    // sorting, filtering and display. In this case, currency (price)
37999		 *    $(document).ready( function() {
38000		 *      $('#example').dataTable( {
38001		 *        "columnDefs": [ {
38002		 *          "targets": [ 0 ],
38003		 *          "data": function ( source, type, val ) {
38004		 *            if (type === 'set') {
38005		 *              source.price = val;
38006		 *              // Store the computed dislay and filter values for efficiency
38007		 *              source.price_display = val=="" ? "" : "$"+numberFormat(val);
38008		 *              source.price_filter  = val=="" ? "" : "$"+numberFormat(val)+" "+val;
38009		 *              return;
38010		 *            }
38011		 *            else if (type === 'display') {
38012		 *              return source.price_display;
38013		 *            }
38014		 *            else if (type === 'filter') {
38015		 *              return source.price_filter;
38016		 *            }
38017		 *            // 'sort', 'type' and undefined all just use the integer
38018		 *            return source.price;
38019		 *          }
38020		 *        } ]
38021		 *      } );
38022		 *    } );
38023		 *
38024		 *  @example
38025		 *    // Using default content
38026		 *    $(document).ready( function() {
38027		 *      $('#example').dataTable( {
38028		 *        "columnDefs": [ {
38029		 *          "targets": [ 0 ],
38030		 *          "data": null,
38031		 *          "defaultContent": "Click to edit"
38032		 *        } ]
38033		 *      } );
38034		 *    } );
38035		 *
38036		 *  @example
38037		 *    // Using array notation - outputting a list from an array
38038		 *    $(document).ready( function() {
38039		 *      $('#example').dataTable( {
38040		 *        "columnDefs": [ {
38041		 *          "targets": [ 0 ],
38042		 *          "data": "name[, ]"
38043		 *        } ]
38044		 *      } );
38045		 *    } );
38046		 *
38047		 */
38048		"mData": null,
38049
38050
38051		/**
38052		 * This property is the rendering partner to `data` and it is suggested that
38053		 * when you want to manipulate data for display (including filtering,
38054		 * sorting etc) without altering the underlying data for the table, use this
38055		 * property. `render` can be considered to be the the read only companion to
38056		 * `data` which is read / write (then as such more complex). Like `data`
38057		 * this option can be given in a number of different ways to effect its
38058		 * behaviour:
38059		 *
38060		 * * `integer` - treated as an array index for the data source. This is the
38061		 *   default that DataTables uses (incrementally increased for each column).
38062		 * * `string` - read an object property from the data source. There are
38063		 *   three 'special' options that can be used in the string to alter how
38064		 *   DataTables reads the data from the source object:
38065		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
38066		 *      Javascript to read from nested objects, so to can the options
38067		 *      specified in `data`. For example: `browser.version` or
38068		 *      `browser.name`. If your object parameter name contains a period, use
38069		 *      `\\` to escape it - i.e. `first\\.name`.
38070		 *    * `[]` - Array notation. DataTables can automatically combine data
38071		 *      from and array source, joining the data with the characters provided
38072		 *      between the two brackets. For example: `name[, ]` would provide a
38073		 *      comma-space separated list from the source array. If no characters
38074		 *      are provided between the brackets, the original array source is
38075		 *      returned.
38076		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
38077		 *      execute a function of the name given. For example: `browser()` for a
38078		 *      simple function on the data source, `browser.version()` for a
38079		 *      function in a nested property or even `browser().version` to get an
38080		 *      object property if the function called returns an object.
38081		 * * `object` - use different data for the different data types requested by
38082		 *   DataTables ('filter', 'display', 'type' or 'sort'). The property names
38083		 *   of the object is the data type the property refers to and the value can
38084		 *   defined using an integer, string or function using the same rules as
38085		 *   `render` normally does. Note that an `_` option _must_ be specified.
38086		 *   This is the default value to use if you haven't specified a value for
38087		 *   the data type requested by DataTables.
38088		 * * `function` - the function given will be executed whenever DataTables
38089		 *   needs to set or get the data for a cell in the column. The function
38090		 *   takes three parameters:
38091		 *    * Parameters:
38092		 *      * {array|object} The data source for the row (based on `data`)
38093		 *      * {string} The type call data requested - this will be 'filter',
38094		 *        'display', 'type' or 'sort'.
38095		 *      * {array|object} The full data source for the row (not based on
38096		 *        `data`)
38097		 *    * Return:
38098		 *      * The return value from the function is what will be used for the
38099		 *        data requested.
38100		 *
38101		 *  @type string|int|function|object|null
38102		 *  @default null Use the data source value.
38103		 *
38104		 *  @name DataTable.defaults.column.render
38105		 *  @dtopt Columns
38106		 *
38107		 *  @example
38108		 *    // Create a comma separated list from an array of objects
38109		 *    $(document).ready( function() {
38110		 *      $('#example').dataTable( {
38111		 *        "ajaxSource": "sources/deep.txt",
38112		 *        "columns": [
38113		 *          { "data": "engine" },
38114		 *          { "data": "browser" },
38115		 *          {
38116		 *            "data": "platform",
38117		 *            "render": "[, ].name"
38118		 *          }
38119		 *        ]
38120		 *      } );
38121		 *    } );
38122		 *
38123		 *  @example
38124		 *    // Execute a function to obtain data
38125		 *    $(document).ready( function() {
38126		 *      $('#example').dataTable( {
38127		 *        "columnDefs": [ {
38128		 *          "targets": [ 0 ],
38129		 *          "data": null, // Use the full data source object for the renderer's source
38130		 *          "render": "browserName()"
38131		 *        } ]
38132		 *      } );
38133		 *    } );
38134		 *
38135		 *  @example
38136		 *    // As an object, extracting different data for the different types
38137		 *    // This would be used with a data source such as:
38138		 *    //   { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
38139		 *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
38140		 *    // (which has both forms) is used for filtering for if a user inputs either format, while
38141		 *    // the formatted phone number is the one that is shown in the table.
38142		 *    $(document).ready( function() {
38143		 *      $('#example').dataTable( {
38144		 *        "columnDefs": [ {
38145		 *          "targets": [ 0 ],
38146		 *          "data": null, // Use the full data source object for the renderer's source
38147		 *          "render": {
38148		 *            "_": "phone",
38149		 *            "filter": "phone_filter",
38150		 *            "display": "phone_display"
38151		 *          }
38152		 *        } ]
38153		 *      } );
38154		 *    } );
38155		 *
38156		 *  @example
38157		 *    // Use as a function to create a link from the data source
38158		 *    $(document).ready( function() {
38159		 *      $('#example').dataTable( {
38160		 *        "columnDefs": [ {
38161		 *          "targets": [ 0 ],
38162		 *          "data": "download_link",
38163		 *          "render": function ( data, type, full ) {
38164		 *            return '<a href="'+data+'">Download</a>';
38165		 *          }
38166		 *        } ]
38167		 *      } );
38168		 *    } );
38169		 */
38170		"mRender": null,
38171
38172
38173		/**
38174		 * Change the cell type created for the column - either TD cells or TH cells. This
38175		 * can be useful as TH cells have semantic meaning in the table body, allowing them
38176		 * to act as a header for a row (you may wish to add scope='row' to the TH elements).
38177		 *  @type string
38178		 *  @default td
38179		 *
38180		 *  @name DataTable.defaults.column.cellType
38181		 *  @dtopt Columns
38182		 *
38183		 *  @example
38184		 *    // Make the first column use TH cells
38185		 *    $(document).ready( function() {
38186		 *      $('#example').dataTable( {
38187		 *        "columnDefs": [ {
38188		 *          "targets": [ 0 ],
38189		 *          "cellType": "th"
38190		 *        } ]
38191		 *      } );
38192		 *    } );
38193		 */
38194		"sCellType": "td",
38195
38196
38197		/**
38198		 * Class to give to each cell in this column.
38199		 *  @type string
38200		 *  @default <i>Empty string</i>
38201		 *
38202		 *  @name DataTable.defaults.column.class
38203		 *  @dtopt Columns
38204		 *
38205		 *  @example
38206		 *    // Using `columnDefs`
38207		 *    $(document).ready( function() {
38208		 *      $('#example').dataTable( {
38209		 *        "columnDefs": [
38210		 *          { "class": "my_class", "targets": [ 0 ] }
38211		 *        ]
38212		 *      } );
38213		 *    } );
38214		 *
38215		 *  @example
38216		 *    // Using `columns`
38217		 *    $(document).ready( function() {
38218		 *      $('#example').dataTable( {
38219		 *        "columns": [
38220		 *          { "class": "my_class" },
38221		 *          null,
38222		 *          null,
38223		 *          null,
38224		 *          null
38225		 *        ]
38226		 *      } );
38227		 *    } );
38228		 */
38229		"sClass": "",
38230
38231		/**
38232		 * When DataTables calculates the column widths to assign to each column,
38233		 * it finds the longest string in each column and then constructs a
38234		 * temporary table and reads the widths from that. The problem with this
38235		 * is that "mmm" is much wider then "iiii", but the latter is a longer
38236		 * string - thus the calculation can go wrong (doing it properly and putting
38237		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
38238		 * a "work around" we provide this option. It will append its value to the
38239		 * text that is found to be the longest string for the column - i.e. padding.
38240		 * Generally you shouldn't need this!
38241		 *  @type string
38242		 *  @default <i>Empty string<i>
38243		 *
38244		 *  @name DataTable.defaults.column.contentPadding
38245		 *  @dtopt Columns
38246		 *
38247		 *  @example
38248		 *    // Using `columns`
38249		 *    $(document).ready( function() {
38250		 *      $('#example').dataTable( {
38251		 *        "columns": [
38252		 *          null,
38253		 *          null,
38254		 *          null,
38255		 *          {
38256		 *            "contentPadding": "mmm"
38257		 *          }
38258		 *        ]
38259		 *      } );
38260		 *    } );
38261		 */
38262		"sContentPadding": "",
38263
38264
38265		/**
38266		 * Allows a default value to be given for a column's data, and will be used
38267		 * whenever a null data source is encountered (this can be because `data`
38268		 * is set to null, or because the data source itself is null).
38269		 *  @type string
38270		 *  @default null
38271		 *
38272		 *  @name DataTable.defaults.column.defaultContent
38273		 *  @dtopt Columns
38274		 *
38275		 *  @example
38276		 *    // Using `columnDefs`
38277		 *    $(document).ready( function() {
38278		 *      $('#example').dataTable( {
38279		 *        "columnDefs": [
38280		 *          {
38281		 *            "data": null,
38282		 *            "defaultContent": "Edit",
38283		 *            "targets": [ -1 ]
38284		 *          }
38285		 *        ]
38286		 *      } );
38287		 *    } );
38288		 *
38289		 *  @example
38290		 *    // Using `columns`
38291		 *    $(document).ready( function() {
38292		 *      $('#example').dataTable( {
38293		 *        "columns": [
38294		 *          null,
38295		 *          null,
38296		 *          null,
38297		 *          {
38298		 *            "data": null,
38299		 *            "defaultContent": "Edit"
38300		 *          }
38301		 *        ]
38302		 *      } );
38303		 *    } );
38304		 */
38305		"sDefaultContent": null,
38306
38307
38308		/**
38309		 * This parameter is only used in DataTables' server-side processing. It can
38310		 * be exceptionally useful to know what columns are being displayed on the
38311		 * client side, and to map these to database fields. When defined, the names
38312		 * also allow DataTables to reorder information from the server if it comes
38313		 * back in an unexpected order (i.e. if you switch your columns around on the
38314		 * client-side, your server-side code does not also need updating).
38315		 *  @type string
38316		 *  @default <i>Empty string</i>
38317		 *
38318		 *  @name DataTable.defaults.column.name
38319		 *  @dtopt Columns
38320		 *
38321		 *  @example
38322		 *    // Using `columnDefs`
38323		 *    $(document).ready( function() {
38324		 *      $('#example').dataTable( {
38325		 *        "columnDefs": [
38326		 *          { "name": "engine", "targets": [ 0 ] },
38327		 *          { "name": "browser", "targets": [ 1 ] },
38328		 *          { "name": "platform", "targets": [ 2 ] },
38329		 *          { "name": "version", "targets": [ 3 ] },
38330		 *          { "name": "grade", "targets": [ 4 ] }
38331		 *        ]
38332		 *      } );
38333		 *    } );
38334		 *
38335		 *  @example
38336		 *    // Using `columns`
38337		 *    $(document).ready( function() {
38338		 *      $('#example').dataTable( {
38339		 *        "columns": [
38340		 *          { "name": "engine" },
38341		 *          { "name": "browser" },
38342		 *          { "name": "platform" },
38343		 *          { "name": "version" },
38344		 *          { "name": "grade" }
38345		 *        ]
38346		 *      } );
38347		 *    } );
38348		 */
38349		"sName": "",
38350
38351
38352		/**
38353		 * Defines a data source type for the ordering which can be used to read
38354		 * real-time information from the table (updating the internally cached
38355		 * version) prior to ordering. This allows ordering to occur on user
38356		 * editable elements such as form inputs.
38357		 *  @type string
38358		 *  @default std
38359		 *
38360		 *  @name DataTable.defaults.column.orderDataType
38361		 *  @dtopt Columns
38362		 *
38363		 *  @example
38364		 *    // Using `columnDefs`
38365		 *    $(document).ready( function() {
38366		 *      $('#example').dataTable( {
38367		 *        "columnDefs": [
38368		 *          { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
38369		 *          { "type": "numeric", "targets": [ 3 ] },
38370		 *          { "orderDataType": "dom-select", "targets": [ 4 ] },
38371		 *          { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
38372		 *        ]
38373		 *      } );
38374		 *    } );
38375		 *
38376		 *  @example
38377		 *    // Using `columns`
38378		 *    $(document).ready( function() {
38379		 *      $('#example').dataTable( {
38380		 *        "columns": [
38381		 *          null,
38382		 *          null,
38383		 *          { "orderDataType": "dom-text" },
38384		 *          { "orderDataType": "dom-text", "type": "numeric" },
38385		 *          { "orderDataType": "dom-select" },
38386		 *          { "orderDataType": "dom-checkbox" }
38387		 *        ]
38388		 *      } );
38389		 *    } );
38390		 */
38391		"sSortDataType": "std",
38392
38393
38394		/**
38395		 * The title of this column.
38396		 *  @type string
38397		 *  @default null <i>Derived from the 'TH' value for this column in the
38398		 *    original HTML table.</i>
38399		 *
38400		 *  @name DataTable.defaults.column.title
38401		 *  @dtopt Columns
38402		 *
38403		 *  @example
38404		 *    // Using `columnDefs`
38405		 *    $(document).ready( function() {
38406		 *      $('#example').dataTable( {
38407		 *        "columnDefs": [
38408		 *          { "title": "My column title", "targets": [ 0 ] }
38409		 *        ]
38410		 *      } );
38411		 *    } );
38412		 *
38413		 *  @example
38414		 *    // Using `columns`
38415		 *    $(document).ready( function() {
38416		 *      $('#example').dataTable( {
38417		 *        "columns": [
38418		 *          { "title": "My column title" },
38419		 *          null,
38420		 *          null,
38421		 *          null,
38422		 *          null
38423		 *        ]
38424		 *      } );
38425		 *    } );
38426		 */
38427		"sTitle": null,
38428
38429
38430		/**
38431		 * The type allows you to specify how the data for this column will be
38432		 * ordered. Four types (string, numeric, date and html (which will strip
38433		 * HTML tags before ordering)) are currently available. Note that only date
38434		 * formats understood by Javascript's Date() object will be accepted as type
38435		 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
38436		 * 'numeric', 'date' or 'html' (by default). Further types can be adding
38437		 * through plug-ins.
38438		 *  @type string
38439		 *  @default null <i>Auto-detected from raw data</i>
38440		 *
38441		 *  @name DataTable.defaults.column.type
38442		 *  @dtopt Columns
38443		 *
38444		 *  @example
38445		 *    // Using `columnDefs`
38446		 *    $(document).ready( function() {
38447		 *      $('#example').dataTable( {
38448		 *        "columnDefs": [
38449		 *          { "type": "html", "targets": [ 0 ] }
38450		 *        ]
38451		 *      } );
38452		 *    } );
38453		 *
38454		 *  @example
38455		 *    // Using `columns`
38456		 *    $(document).ready( function() {
38457		 *      $('#example').dataTable( {
38458		 *        "columns": [
38459		 *          { "type": "html" },
38460		 *          null,
38461		 *          null,
38462		 *          null,
38463		 *          null
38464		 *        ]
38465		 *      } );
38466		 *    } );
38467		 */
38468		"sType": null,
38469
38470
38471		/**
38472		 * Defining the width of the column, this parameter may take any CSS value
38473		 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
38474		 * been given a specific width through this interface ensuring that the table
38475		 * remains readable.
38476		 *  @type string
38477		 *  @default null <i>Automatic</i>
38478		 *
38479		 *  @name DataTable.defaults.column.width
38480		 *  @dtopt Columns
38481		 *
38482		 *  @example
38483		 *    // Using `columnDefs`
38484		 *    $(document).ready( function() {
38485		 *      $('#example').dataTable( {
38486		 *        "columnDefs": [
38487		 *          { "width": "20%", "targets": [ 0 ] }
38488		 *        ]
38489		 *      } );
38490		 *    } );
38491		 *
38492		 *  @example
38493		 *    // Using `columns`
38494		 *    $(document).ready( function() {
38495		 *      $('#example').dataTable( {
38496		 *        "columns": [
38497		 *          { "width": "20%" },
38498		 *          null,
38499		 *          null,
38500		 *          null,
38501		 *          null
38502		 *        ]
38503		 *      } );
38504		 *    } );
38505		 */
38506		"sWidth": null
38507	};
38508
38509	_fnHungarianMap( DataTable.defaults.column );
38510
38511
38512
38513	/**
38514	 * DataTables settings object - this holds all the information needed for a
38515	 * given table, including configuration, data and current application of the
38516	 * table options. DataTables does not have a single instance for each DataTable
38517	 * with the settings attached to that instance, but rather instances of the
38518	 * DataTable "class" are created on-the-fly as needed (typically by a
38519	 * $().dataTable() call) and the settings object is then applied to that
38520	 * instance.
38521	 *
38522	 * Note that this object is related to {@link DataTable.defaults} but this
38523	 * one is the internal data store for DataTables's cache of columns. It should
38524	 * NOT be manipulated outside of DataTables. Any configuration should be done
38525	 * through the initialisation options.
38526	 *  @namespace
38527	 *  @todo Really should attach the settings object to individual instances so we
38528	 *    don't need to create new instances on each $().dataTable() call (if the
38529	 *    table already exists). It would also save passing oSettings around and
38530	 *    into every single function. However, this is a very significant
38531	 *    architecture change for DataTables and will almost certainly break
38532	 *    backwards compatibility with older installations. This is something that
38533	 *    will be done in 2.0.
38534	 */
38535	DataTable.models.oSettings = {
38536		/**
38537		 * Primary features of DataTables and their enablement state.
38538		 *  @namespace
38539		 */
38540		"oFeatures": {
38541
38542			/**
38543			 * Flag to say if DataTables should automatically try to calculate the
38544			 * optimum table and columns widths (true) or not (false).
38545			 * Note that this parameter will be set by the initialisation routine. To
38546			 * set a default use {@link DataTable.defaults}.
38547			 *  @type boolean
38548			 */
38549			"bAutoWidth": null,
38550
38551			/**
38552			 * Delay the creation of TR and TD elements until they are actually
38553			 * needed by a driven page draw. This can give a significant speed
38554			 * increase for Ajax source and Javascript source data, but makes no
38555			 * difference at all fro DOM and server-side processing tables.
38556			 * Note that this parameter will be set by the initialisation routine. To
38557			 * set a default use {@link DataTable.defaults}.
38558			 *  @type boolean
38559			 */
38560			"bDeferRender": null,
38561
38562			/**
38563			 * Enable filtering on the table or not. Note that if this is disabled
38564			 * then there is no filtering at all on the table, including fnFilter.
38565			 * To just remove the filtering input use sDom and remove the 'f' option.
38566			 * Note that this parameter will be set by the initialisation routine. To
38567			 * set a default use {@link DataTable.defaults}.
38568			 *  @type boolean
38569			 */
38570			"bFilter": null,
38571
38572			/**
38573			 * Table information element (the 'Showing x of y records' div) enable
38574			 * flag.
38575			 * Note that this parameter will be set by the initialisation routine. To
38576			 * set a default use {@link DataTable.defaults}.
38577			 *  @type boolean
38578			 */
38579			"bInfo": null,
38580
38581			/**
38582			 * Present a user control allowing the end user to change the page size
38583			 * when pagination is enabled.
38584			 * Note that this parameter will be set by the initialisation routine. To
38585			 * set a default use {@link DataTable.defaults}.
38586			 *  @type boolean
38587			 */
38588			"bLengthChange": null,
38589
38590			/**
38591			 * Pagination enabled or not. Note that if this is disabled then length
38592			 * changing must also be disabled.
38593			 * Note that this parameter will be set by the initialisation routine. To
38594			 * set a default use {@link DataTable.defaults}.
38595			 *  @type boolean
38596			 */
38597			"bPaginate": null,
38598
38599			/**
38600			 * Processing indicator enable flag whenever DataTables is enacting a
38601			 * user request - typically an Ajax request for server-side processing.
38602			 * Note that this parameter will be set by the initialisation routine. To
38603			 * set a default use {@link DataTable.defaults}.
38604			 *  @type boolean
38605			 */
38606			"bProcessing": null,
38607
38608			/**
38609			 * Server-side processing enabled flag - when enabled DataTables will
38610			 * get all data from the server for every draw - there is no filtering,
38611			 * sorting or paging done on the client-side.
38612			 * Note that this parameter will be set by the initialisation routine. To
38613			 * set a default use {@link DataTable.defaults}.
38614			 *  @type boolean
38615			 */
38616			"bServerSide": null,
38617
38618			/**
38619			 * Sorting enablement flag.
38620			 * Note that this parameter will be set by the initialisation routine. To
38621			 * set a default use {@link DataTable.defaults}.
38622			 *  @type boolean
38623			 */
38624			"bSort": null,
38625
38626			/**
38627			 * Multi-column sorting
38628			 * Note that this parameter will be set by the initialisation routine. To
38629			 * set a default use {@link DataTable.defaults}.
38630			 *  @type boolean
38631			 */
38632			"bSortMulti": null,
38633
38634			/**
38635			 * Apply a class to the columns which are being sorted to provide a
38636			 * visual highlight or not. This can slow things down when enabled since
38637			 * there is a lot of DOM interaction.
38638			 * Note that this parameter will be set by the initialisation routine. To
38639			 * set a default use {@link DataTable.defaults}.
38640			 *  @type boolean
38641			 */
38642			"bSortClasses": null,
38643
38644			/**
38645			 * State saving enablement flag.
38646			 * Note that this parameter will be set by the initialisation routine. To
38647			 * set a default use {@link DataTable.defaults}.
38648			 *  @type boolean
38649			 */
38650			"bStateSave": null
38651		},
38652
38653
38654		/**
38655		 * Scrolling settings for a table.
38656		 *  @namespace
38657		 */
38658		"oScroll": {
38659			/**
38660			 * When the table is shorter in height than sScrollY, collapse the
38661			 * table container down to the height of the table (when true).
38662			 * Note that this parameter will be set by the initialisation routine. To
38663			 * set a default use {@link DataTable.defaults}.
38664			 *  @type boolean
38665			 */
38666			"bCollapse": null,
38667
38668			/**
38669			 * Width of the scrollbar for the web-browser's platform. Calculated
38670			 * during table initialisation.
38671			 *  @type int
38672			 *  @default 0
38673			 */
38674			"iBarWidth": 0,
38675
38676			/**
38677			 * Viewport width for horizontal scrolling. Horizontal scrolling is
38678			 * disabled if an empty string.
38679			 * Note that this parameter will be set by the initialisation routine. To
38680			 * set a default use {@link DataTable.defaults}.
38681			 *  @type string
38682			 */
38683			"sX": null,
38684
38685			/**
38686			 * Width to expand the table to when using x-scrolling. Typically you
38687			 * should not need to use this.
38688			 * Note that this parameter will be set by the initialisation routine. To
38689			 * set a default use {@link DataTable.defaults}.
38690			 *  @type string
38691			 *  @deprecated
38692			 */
38693			"sXInner": null,
38694
38695			/**
38696			 * Viewport height for vertical scrolling. Vertical scrolling is disabled
38697			 * if an empty string.
38698			 * Note that this parameter will be set by the initialisation routine. To
38699			 * set a default use {@link DataTable.defaults}.
38700			 *  @type string
38701			 */
38702			"sY": null
38703		},
38704
38705		/**
38706		 * Language information for the table.
38707		 *  @namespace
38708		 *  @extends DataTable.defaults.oLanguage
38709		 */
38710		"oLanguage": {
38711			/**
38712			 * Information callback function. See
38713			 * {@link DataTable.defaults.fnInfoCallback}
38714			 *  @type function
38715			 *  @default null
38716			 */
38717			"fnInfoCallback": null
38718		},
38719
38720		/**
38721		 * Browser support parameters
38722		 *  @namespace
38723		 */
38724		"oBrowser": {
38725			/**
38726			 * Indicate if the browser incorrectly calculates width:100% inside a
38727			 * scrolling element (IE6/7)
38728			 *  @type boolean
38729			 *  @default false
38730			 */
38731			"bScrollOversize": false,
38732
38733			/**
38734			 * Determine if the vertical scrollbar is on the right or left of the
38735			 * scrolling container - needed for rtl language layout, although not
38736			 * all browsers move the scrollbar (Safari).
38737			 *  @type boolean
38738			 *  @default false
38739			 */
38740			"bScrollbarLeft": false,
38741
38742			/**
38743			 * Flag for if `getBoundingClientRect` is fully supported or not
38744			 *  @type boolean
38745			 *  @default false
38746			 */
38747			"bBounding": false,
38748
38749			/**
38750			 * Browser scrollbar width
38751			 *  @type integer
38752			 *  @default 0
38753			 */
38754			"barWidth": 0
38755		},
38756
38757
38758		"ajax": null,
38759
38760
38761		/**
38762		 * Array referencing the nodes which are used for the features. The
38763		 * parameters of this object match what is allowed by sDom - i.e.
38764		 *   <ul>
38765		 *     <li>'l' - Length changing</li>
38766		 *     <li>'f' - Filtering input</li>
38767		 *     <li>'t' - The table!</li>
38768		 *     <li>'i' - Information</li>
38769		 *     <li>'p' - Pagination</li>
38770		 *     <li>'r' - pRocessing</li>
38771		 *   </ul>
38772		 *  @type array
38773		 *  @default []
38774		 */
38775		"aanFeatures": [],
38776
38777		/**
38778		 * Store data information - see {@link DataTable.models.oRow} for detailed
38779		 * information.
38780		 *  @type array
38781		 *  @default []
38782		 */
38783		"aoData": [],
38784
38785		/**
38786		 * Array of indexes which are in the current display (after filtering etc)
38787		 *  @type array
38788		 *  @default []
38789		 */
38790		"aiDisplay": [],
38791
38792		/**
38793		 * Array of indexes for display - no filtering
38794		 *  @type array
38795		 *  @default []
38796		 */
38797		"aiDisplayMaster": [],
38798
38799		/**
38800		 * Map of row ids to data indexes
38801		 *  @type object
38802		 *  @default {}
38803		 */
38804		"aIds": {},
38805
38806		/**
38807		 * Store information about each column that is in use
38808		 *  @type array
38809		 *  @default []
38810		 */
38811		"aoColumns": [],
38812
38813		/**
38814		 * Store information about the table's header
38815		 *  @type array
38816		 *  @default []
38817		 */
38818		"aoHeader": [],
38819
38820		/**
38821		 * Store information about the table's footer
38822		 *  @type array
38823		 *  @default []
38824		 */
38825		"aoFooter": [],
38826
38827		/**
38828		 * Store the applied global search information in case we want to force a
38829		 * research or compare the old search to a new one.
38830		 * Note that this parameter will be set by the initialisation routine. To
38831		 * set a default use {@link DataTable.defaults}.
38832		 *  @namespace
38833		 *  @extends DataTable.models.oSearch
38834		 */
38835		"oPreviousSearch": {},
38836
38837		/**
38838		 * Store the applied search for each column - see
38839		 * {@link DataTable.models.oSearch} for the format that is used for the
38840		 * filtering information for each column.
38841		 *  @type array
38842		 *  @default []
38843		 */
38844		"aoPreSearchCols": [],
38845
38846		/**
38847		 * Sorting that is applied to the table. Note that the inner arrays are
38848		 * used in the following manner:
38849		 * <ul>
38850		 *   <li>Index 0 - column number</li>
38851		 *   <li>Index 1 - current sorting direction</li>
38852		 * </ul>
38853		 * Note that this parameter will be set by the initialisation routine. To
38854		 * set a default use {@link DataTable.defaults}.
38855		 *  @type array
38856		 *  @todo These inner arrays should really be objects
38857		 */
38858		"aaSorting": null,
38859
38860		/**
38861		 * Sorting that is always applied to the table (i.e. prefixed in front of
38862		 * aaSorting).
38863		 * Note that this parameter will be set by the initialisation routine. To
38864		 * set a default use {@link DataTable.defaults}.
38865		 *  @type array
38866		 *  @default []
38867		 */
38868		"aaSortingFixed": [],
38869
38870		/**
38871		 * Classes to use for the striping of a table.
38872		 * Note that this parameter will be set by the initialisation routine. To
38873		 * set a default use {@link DataTable.defaults}.
38874		 *  @type array
38875		 *  @default []
38876		 */
38877		"asStripeClasses": null,
38878
38879		/**
38880		 * If restoring a table - we should restore its striping classes as well
38881		 *  @type array
38882		 *  @default []
38883		 */
38884		"asDestroyStripes": [],
38885
38886		/**
38887		 * If restoring a table - we should restore its width
38888		 *  @type int
38889		 *  @default 0
38890		 */
38891		"sDestroyWidth": 0,
38892
38893		/**
38894		 * Callback functions array for every time a row is inserted (i.e. on a draw).
38895		 *  @type array
38896		 *  @default []
38897		 */
38898		"aoRowCallback": [],
38899
38900		/**
38901		 * Callback functions for the header on each draw.
38902		 *  @type array
38903		 *  @default []
38904		 */
38905		"aoHeaderCallback": [],
38906
38907		/**
38908		 * Callback function for the footer on each draw.
38909		 *  @type array
38910		 *  @default []
38911		 */
38912		"aoFooterCallback": [],
38913
38914		/**
38915		 * Array of callback functions for draw callback functions
38916		 *  @type array
38917		 *  @default []
38918		 */
38919		"aoDrawCallback": [],
38920
38921		/**
38922		 * Array of callback functions for row created function
38923		 *  @type array
38924		 *  @default []
38925		 */
38926		"aoRowCreatedCallback": [],
38927
38928		/**
38929		 * Callback functions for just before the table is redrawn. A return of
38930		 * false will be used to cancel the draw.
38931		 *  @type array
38932		 *  @default []
38933		 */
38934		"aoPreDrawCallback": [],
38935
38936		/**
38937		 * Callback functions for when the table has been initialised.
38938		 *  @type array
38939		 *  @default []
38940		 */
38941		"aoInitComplete": [],
38942
38943
38944		/**
38945		 * Callbacks for modifying the settings to be stored for state saving, prior to
38946		 * saving state.
38947		 *  @type array
38948		 *  @default []
38949		 */
38950		"aoStateSaveParams": [],
38951
38952		/**
38953		 * Callbacks for modifying the settings that have been stored for state saving
38954		 * prior to using the stored values to restore the state.
38955		 *  @type array
38956		 *  @default []
38957		 */
38958		"aoStateLoadParams": [],
38959
38960		/**
38961		 * Callbacks for operating on the settings object once the saved state has been
38962		 * loaded
38963		 *  @type array
38964		 *  @default []
38965		 */
38966		"aoStateLoaded": [],
38967
38968		/**
38969		 * Cache the table ID for quick access
38970		 *  @type string
38971		 *  @default <i>Empty string</i>
38972		 */
38973		"sTableId": "",
38974
38975		/**
38976		 * The TABLE node for the main table
38977		 *  @type node
38978		 *  @default null
38979		 */
38980		"nTable": null,
38981
38982		/**
38983		 * Permanent ref to the thead element
38984		 *  @type node
38985		 *  @default null
38986		 */
38987		"nTHead": null,
38988
38989		/**
38990		 * Permanent ref to the tfoot element - if it exists
38991		 *  @type node
38992		 *  @default null
38993		 */
38994		"nTFoot": null,
38995
38996		/**
38997		 * Permanent ref to the tbody element
38998		 *  @type node
38999		 *  @default null
39000		 */
39001		"nTBody": null,
39002
39003		/**
39004		 * Cache the wrapper node (contains all DataTables controlled elements)
39005		 *  @type node
39006		 *  @default null
39007		 */
39008		"nTableWrapper": null,
39009
39010		/**
39011		 * Indicate if when using server-side processing the loading of data
39012		 * should be deferred until the second draw.
39013		 * Note that this parameter will be set by the initialisation routine. To
39014		 * set a default use {@link DataTable.defaults}.
39015		 *  @type boolean
39016		 *  @default false
39017		 */
39018		"bDeferLoading": false,
39019
39020		/**
39021		 * Indicate if all required information has been read in
39022		 *  @type boolean
39023		 *  @default false
39024		 */
39025		"bInitialised": false,
39026
39027		/**
39028		 * Information about open rows. Each object in the array has the parameters
39029		 * 'nTr' and 'nParent'
39030		 *  @type array
39031		 *  @default []
39032		 */
39033		"aoOpenRows": [],
39034
39035		/**
39036		 * Dictate the positioning of DataTables' control elements - see
39037		 * {@link DataTable.model.oInit.sDom}.
39038		 * Note that this parameter will be set by the initialisation routine. To
39039		 * set a default use {@link DataTable.defaults}.
39040		 *  @type string
39041		 *  @default null
39042		 */
39043		"sDom": null,
39044
39045		/**
39046		 * Search delay (in mS)
39047		 *  @type integer
39048		 *  @default null
39049		 */
39050		"searchDelay": null,
39051
39052		/**
39053		 * Which type of pagination should be used.
39054		 * Note that this parameter will be set by the initialisation routine. To
39055		 * set a default use {@link DataTable.defaults}.
39056		 *  @type string
39057		 *  @default two_button
39058		 */
39059		"sPaginationType": "two_button",
39060
39061		/**
39062		 * The state duration (for `stateSave`) in seconds.
39063		 * Note that this parameter will be set by the initialisation routine. To
39064		 * set a default use {@link DataTable.defaults}.
39065		 *  @type int
39066		 *  @default 0
39067		 */
39068		"iStateDuration": 0,
39069
39070		/**
39071		 * Array of callback functions for state saving. Each array element is an
39072		 * object with the following parameters:
39073		 *   <ul>
39074		 *     <li>function:fn - function to call. Takes two parameters, oSettings
39075		 *       and the JSON string to save that has been thus far created. Returns
39076		 *       a JSON string to be inserted into a json object
39077		 *       (i.e. '"param": [ 0, 1, 2]')</li>
39078		 *     <li>string:sName - name of callback</li>
39079		 *   </ul>
39080		 *  @type array
39081		 *  @default []
39082		 */
39083		"aoStateSave": [],
39084
39085		/**
39086		 * Array of callback functions for state loading. Each array element is an
39087		 * object with the following parameters:
39088		 *   <ul>
39089		 *     <li>function:fn - function to call. Takes two parameters, oSettings
39090		 *       and the object stored. May return false to cancel state loading</li>
39091		 *     <li>string:sName - name of callback</li>
39092		 *   </ul>
39093		 *  @type array
39094		 *  @default []
39095		 */
39096		"aoStateLoad": [],
39097
39098		/**
39099		 * State that was saved. Useful for back reference
39100		 *  @type object
39101		 *  @default null
39102		 */
39103		"oSavedState": null,
39104
39105		/**
39106		 * State that was loaded. Useful for back reference
39107		 *  @type object
39108		 *  @default null
39109		 */
39110		"oLoadedState": null,
39111
39112		/**
39113		 * Source url for AJAX data for the table.
39114		 * Note that this parameter will be set by the initialisation routine. To
39115		 * set a default use {@link DataTable.defaults}.
39116		 *  @type string
39117		 *  @default null
39118		 */
39119		"sAjaxSource": null,
39120
39121		/**
39122		 * Property from a given object from which to read the table data from. This
39123		 * can be an empty string (when not server-side processing), in which case
39124		 * it is  assumed an an array is given directly.
39125		 * Note that this parameter will be set by the initialisation routine. To
39126		 * set a default use {@link DataTable.defaults}.
39127		 *  @type string
39128		 */
39129		"sAjaxDataProp": null,
39130
39131		/**
39132		 * Note if draw should be blocked while getting data
39133		 *  @type boolean
39134		 *  @default true
39135		 */
39136		"bAjaxDataGet": true,
39137
39138		/**
39139		 * The last jQuery XHR object that was used for server-side data gathering.
39140		 * This can be used for working with the XHR information in one of the
39141		 * callbacks
39142		 *  @type object
39143		 *  @default null
39144		 */
39145		"jqXHR": null,
39146
39147		/**
39148		 * JSON returned from the server in the last Ajax request
39149		 *  @type object
39150		 *  @default undefined
39151		 */
39152		"json": undefined,
39153
39154		/**
39155		 * Data submitted as part of the last Ajax request
39156		 *  @type object
39157		 *  @default undefined
39158		 */
39159		"oAjaxData": undefined,
39160
39161		/**
39162		 * Function to get the server-side data.
39163		 * Note that this parameter will be set by the initialisation routine. To
39164		 * set a default use {@link DataTable.defaults}.
39165		 *  @type function
39166		 */
39167		"fnServerData": null,
39168
39169		/**
39170		 * Functions which are called prior to sending an Ajax request so extra
39171		 * parameters can easily be sent to the server
39172		 *  @type array
39173		 *  @default []
39174		 */
39175		"aoServerParams": [],
39176
39177		/**
39178		 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
39179		 * required).
39180		 * Note that this parameter will be set by the initialisation routine. To
39181		 * set a default use {@link DataTable.defaults}.
39182		 *  @type string
39183		 */
39184		"sServerMethod": null,
39185
39186		/**
39187		 * Format numbers for display.
39188		 * Note that this parameter will be set by the initialisation routine. To
39189		 * set a default use {@link DataTable.defaults}.
39190		 *  @type function
39191		 */
39192		"fnFormatNumber": null,
39193
39194		/**
39195		 * List of options that can be used for the user selectable length menu.
39196		 * Note that this parameter will be set by the initialisation routine. To
39197		 * set a default use {@link DataTable.defaults}.
39198		 *  @type array
39199		 *  @default []
39200		 */
39201		"aLengthMenu": null,
39202
39203		/**
39204		 * Counter for the draws that the table does. Also used as a tracker for
39205		 * server-side processing
39206		 *  @type int
39207		 *  @default 0
39208		 */
39209		"iDraw": 0,
39210
39211		/**
39212		 * Indicate if a redraw is being done - useful for Ajax
39213		 *  @type boolean
39214		 *  @default false
39215		 */
39216		"bDrawing": false,
39217
39218		/**
39219		 * Draw index (iDraw) of the last error when parsing the returned data
39220		 *  @type int
39221		 *  @default -1
39222		 */
39223		"iDrawError": -1,
39224
39225		/**
39226		 * Paging display length
39227		 *  @type int
39228		 *  @default 10
39229		 */
39230		"_iDisplayLength": 10,
39231
39232		/**
39233		 * Paging start point - aiDisplay index
39234		 *  @type int
39235		 *  @default 0
39236		 */
39237		"_iDisplayStart": 0,
39238
39239		/**
39240		 * Server-side processing - number of records in the result set
39241		 * (i.e. before filtering), Use fnRecordsTotal rather than
39242		 * this property to get the value of the number of records, regardless of
39243		 * the server-side processing setting.
39244		 *  @type int
39245		 *  @default 0
39246		 *  @private
39247		 */
39248		"_iRecordsTotal": 0,
39249
39250		/**
39251		 * Server-side processing - number of records in the current display set
39252		 * (i.e. after filtering). Use fnRecordsDisplay rather than
39253		 * this property to get the value of the number of records, regardless of
39254		 * the server-side processing setting.
39255		 *  @type boolean
39256		 *  @default 0
39257		 *  @private
39258		 */
39259		"_iRecordsDisplay": 0,
39260
39261		/**
39262		 * Flag to indicate if jQuery UI marking and classes should be used.
39263		 * Note that this parameter will be set by the initialisation routine. To
39264		 * set a default use {@link DataTable.defaults}.
39265		 *  @type boolean
39266		 */
39267		"bJUI": null,
39268
39269		/**
39270		 * The classes to use for the table
39271		 *  @type object
39272		 *  @default {}
39273		 */
vendor: 5,028 bytes, lines 39274-39497
39274		"oClasses": {},
39275
39276		/**
39277		 * Flag attached to the settings object so you can check in the draw
39278		 * callback if filtering has been done in the draw. Deprecated in favour of
39279		 * events.
39280		 *  @type boolean
39281		 *  @default false
39282		 *  @deprecated
39283		 */
39284		"bFiltered": false,
39285
39286		/**
39287		 * Flag attached to the settings object so you can check in the draw
39288		 * callback if sorting has been done in the draw. Deprecated in favour of
39289		 * events.
39290		 *  @type boolean
39291		 *  @default false
39292		 *  @deprecated
39293		 */
39294		"bSorted": false,
39295
39296		/**
39297		 * Indicate that if multiple rows are in the header and there is more than
39298		 * one unique cell per column, if the top one (true) or bottom one (false)
39299		 * should be used for sorting / title by DataTables.
39300		 * Note that this parameter will be set by the initialisation routine. To
39301		 * set a default use {@link DataTable.defaults}.
39302		 *  @type boolean
39303		 */
39304		"bSortCellsTop": null,
39305
39306		/**
39307		 * Initialisation object that is used for the table
39308		 *  @type object
39309		 *  @default null
39310		 */
39311		"oInit": null,
39312
39313		/**
39314		 * Destroy callback functions - for plug-ins to attach themselves to the
39315		 * destroy so they can clean up markup and events.
39316		 *  @type array
39317		 *  @default []
39318		 */
39319		"aoDestroyCallback": [],
39320
39321
39322		/**
39323		 * Get the number of records in the current record set, before filtering
39324		 *  @type function
39325		 */
39326		"fnRecordsTotal": function ()
39327		{
39328			return _fnDataSource( this ) == 'ssp' ?
39329				this._iRecordsTotal * 1 :
39330				this.aiDisplayMaster.length;
39331		},
39332
39333		/**
39334		 * Get the number of records in the current record set, after filtering
39335		 *  @type function
39336		 */
39337		"fnRecordsDisplay": function ()
39338		{
39339			return _fnDataSource( this ) == 'ssp' ?
39340				this._iRecordsDisplay * 1 :
39341				this.aiDisplay.length;
39342		},
39343
39344		/**
39345		 * Get the display end point - aiDisplay index
39346		 *  @type function
39347		 */
39348		"fnDisplayEnd": function ()
39349		{
39350			var
39351				len      = this._iDisplayLength,
39352				start    = this._iDisplayStart,
39353				calc     = start + len,
39354				records  = this.aiDisplay.length,
39355				features = this.oFeatures,
39356				paginate = features.bPaginate;
39357
39358			if ( features.bServerSide ) {
39359				return paginate === false || len === -1 ?
39360					start + records :
39361					Math.min( start+len, this._iRecordsDisplay );
39362			}
39363			else {
39364				return ! paginate || calc>records || len===-1 ?
39365					records :
39366					calc;
39367			}
39368		},
39369
39370		/**
39371		 * The DataTables object for this table
39372		 *  @type object
39373		 *  @default null
39374		 */
39375		"oInstance": null,
39376
39377		/**
39378		 * Unique identifier for each instance of the DataTables object. If there
39379		 * is an ID on the table node, then it takes that value, otherwise an
39380		 * incrementing internal counter is used.
39381		 *  @type string
39382		 *  @default null
39383		 */
39384		"sInstance": null,
39385
39386		/**
39387		 * tabindex attribute value that is added to DataTables control elements, allowing
39388		 * keyboard navigation of the table and its controls.
39389		 */
39390		"iTabIndex": 0,
39391
39392		/**
39393		 * DIV container for the footer scrolling table if scrolling
39394		 */
39395		"nScrollHead": null,
39396
39397		/**
39398		 * DIV container for the footer scrolling table if scrolling
39399		 */
39400		"nScrollFoot": null,
39401
39402		/**
39403		 * Last applied sort
39404		 *  @type array
39405		 *  @default []
39406		 */
39407		"aLastSort": [],
39408
39409		/**
39410		 * Stored plug-in instances
39411		 *  @type object
39412		 *  @default {}
39413		 */
39414		"oPlugins": {},
39415
39416		/**
39417		 * Function used to get a row's id from the row's data
39418		 *  @type function
39419		 *  @default null
39420		 */
39421		"rowIdFn": null,
39422
39423		/**
39424		 * Data location where to store a row's id
39425		 *  @type string
39426		 *  @default null
39427		 */
39428		"rowId": null
39429	};
39430
39431	/**
39432	 * Extension object for DataTables that is used to provide all extension
39433	 * options.
39434	 *
39435	 * Note that the `DataTable.ext` object is available through
39436	 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
39437	 * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
39438	 *  @namespace
39439	 *  @extends DataTable.models.ext
39440	 */
39441
39442
39443	/**
39444	 * DataTables extensions
39445	 *
39446	 * This namespace acts as a collection area for plug-ins that can be used to
39447	 * extend DataTables capabilities. Indeed many of the build in methods
39448	 * use this method to provide their own capabilities (sorting methods for
39449	 * example).
39450	 *
39451	 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
39452	 * reasons
39453	 *
39454	 *  @namespace
39455	 */
39456	DataTable.ext = _ext = {
39457		/**
39458		 * Buttons. For use with the Buttons extension for DataTables. This is
39459		 * defined here so other extensions can define buttons regardless of load
39460		 * order. It is _not_ used by DataTables core.
39461		 *
39462		 *  @type object
39463		 *  @default {}
39464		 */
39465		buttons: {},
39466
39467
39468		/**
39469		 * Element class names
39470		 *
39471		 *  @type object
39472		 *  @default {}
39473		 */
39474		classes: {},
39475
39476
39477		/**
39478		 * DataTables build type (expanded by the download builder)
39479		 *
39480		 *  @type string
39481		 */
39482		builder: "-source-",
39483
39484
39485		/**
39486		 * Error reporting.
39487		 *
39488		 * How should DataTables report an error. Can take the value 'alert',
39489		 * 'throw', 'none' or a function.
39490		 *
39491		 *  @type string|function
39492		 *  @default alert
39493		 */
39494		errMode: "alert",
39495
39496
39497		/**
39498		 * Feature plug-ins.
39499		 *
39500		 * This is an array of objects which describe the feature plug-ins that are
39501		 * available to DataTables. These feature plug-ins are then available for
39502		 * use through the `dom` initialisation option.
39503		 *
39504		 * Each feature plug-in is described by an object which must have the
39505		 * following properties:
39506		 *
39507		 * * `fnInit` - function that is used to initialise the plug-in,
39508		 * * `cFeature` - a character so the feature can be enabled by the `dom`
39509		 *   instillation option. This is case sensitive.
39510		 *
39511		 * The `fnInit` function has the following input parameters:
39512		 *
39513		 * 1. `{object}` DataTables settings object: see
39514		 *    {@link DataTable.models.oSettings}
39515		 *
39516		 * And the following return is expected:
39517		 *
39518		 * * {node|null} The element which contains your feature. Note that the
39519		 *   return may also be void if your plug-in does not require to inject any
39520		 *   DOM elements into DataTables control (`dom`) - for example this might
39521		 *   be useful when developing a plug-in which allows table control via
39522		 *   keyboard entry
39523		 *
39524		 *  @type array
39525		 *
39526		 *  @example
39527		 *    $.fn.dataTable.ext.features.push( {
39528		 *      "fnInit": function( oSettings ) {
39529		 *        return new TableTools( { "oDTSettings": oSettings } );
39530		 *      },
39531		 *      "cFeature": "T"
39532		 *    } );
39533		 */
39534		feature: [],
39535
39536
39537		/**
39538		 * Row searching.
39539		 *
39540		 * This method of searching is complimentary to the default type based
39541		 * searching, and a lot more comprehensive as it allows you complete control
39542		 * over the searching logic. Each element in this array is a function
39543		 * (parameters described below) that is called for every row in the table,
39544		 * and your logic decides if it should be included in the searching data set
39545		 * or not.
39546		 *
39547		 * Searching functions have the following input parameters:
39548		 *
39549		 * 1. `{object}` DataTables settings object: see
39550		 *    {@link DataTable.models.oSettings}
39551		 * 2. `{array|object}` Data for the row to be processed (same as the
39552		 *    original format that was passed in as the data source, or an array
39553		 *    from a DOM data source
39554		 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
39555		 *    can be useful to retrieve the `TR` element if you need DOM interaction.
39556		 *
39557		 * And the following return is expected:
39558		 *
39559		 * * {boolean} Include the row in the searched result set (true) or not
39560		 *   (false)
39561		 *
39562		 * Note that as with the main search ability in DataTables, technically this
39563		 * is "filtering", since it is subtractive. However, for consistency in
39564		 * naming we call it searching here.
39565		 *
39566		 *  @type array
39567		 *  @default []
39568		 *
39569		 *  @example
39570		 *    // The following example shows custom search being applied to the
39571		 *    // fourth column (i.e. the data[3] index) based on two input values
39572		 *    // from the end-user, matching the data in a certain range.
39573		 *    $.fn.dataTable.ext.search.push(
39574		 *      function( settings, data, dataIndex ) {
39575		 *        var min = document.getElementById('min').value * 1;
39576		 *        var max = document.getElementById('max').value * 1;
39577		 *        var version = data[3] == "-" ? 0 : data[3]*1;
39578		 *
39579		 *        if ( min == "" && max == "" ) {
39580		 *          return true;
39581		 *        }
39582		 *        else if ( min == "" && version < max ) {
39583		 *          return true;
39584		 *        }
39585		 *        else if ( min < version && "" == max ) {
39586		 *          return true;
39587		 *        }
39588		 *        else if ( min < version && version < max ) {
39589		 *          return true;
39590		 *        }
39591		 *        return false;
39592		 *      }
39593		 *    );
39594		 */
39595		search: [],
39596
39597
39598		/**
39599		 * Selector extensions
39600		 *
39601		 * The `selector` option can be used to extend the options available for the
39602		 * selector modifier options (`selector-modifier` object data type) that
39603		 * each of the three built in selector types offer (row, column and cell +
39604		 * their plural counterparts). For example the Select extension uses this
39605		 * mechanism to provide an option to select only rows, columns and cells
39606		 * that have been marked as selected by the end user (`{selected: true}`),
39607		 * which can be used in conjunction with the existing built in selector
39608		 * options.
39609		 *
39610		 * Each property is an array to which functions can be pushed. The functions
39611		 * take three attributes:
39612		 *
39613		 * * Settings object for the host table
39614		 * * Options object (`selector-modifier` object type)
39615		 * * Array of selected item indexes
39616		 *
39617		 * The return is an array of the resulting item indexes after the custom
39618		 * selector has been applied.
39619		 *
39620		 *  @type object
39621		 */
39622		selector: {
39623			cell: [],
39624			column: [],
39625			row: []
39626		},
39627
39628
39629		/**
39630		 * Internal functions, exposed for used in plug-ins.
39631		 *
39632		 * Please note that you should not need to use the internal methods for
39633		 * anything other than a plug-in (and even then, try to avoid if possible).
39634		 * The internal function may change between releases.
39635		 *
39636		 *  @type object
39637		 *  @default {}
39638		 */
39639		internal: {},
39640
39641
39642		/**
39643		 * Legacy configuration options. Enable and disable legacy options that
39644		 * are available in DataTables.
39645		 *
39646		 *  @type object
39647		 */
39648		legacy: {
39649			/**
39650			 * Enable / disable DataTables 1.9 compatible server-side processing
39651			 * requests
39652			 *
39653			 *  @type boolean
39654			 *  @default null
39655			 */
39656			ajax: null
39657		},
39658
39659
39660		/**
39661		 * Pagination plug-in methods.
39662		 *
39663		 * Each entry in this object is a function and defines which buttons should
39664		 * be shown by the pagination rendering method that is used for the table:
39665		 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
39666		 * buttons are displayed in the document, while the functions here tell it
39667		 * what buttons to display. This is done by returning an array of button
39668		 * descriptions (what each button will do).
39669		 *
39670		 * Pagination types (the four built in options and any additional plug-in
39671		 * options defined here) can be used through the `paginationType`
39672		 * initialisation parameter.
39673		 *
39674		 * The functions defined take two parameters:
39675		 *
39676		 * 1. `{int} page` The current page index
39677		 * 2. `{int} pages` The number of pages in the table
39678		 *
39679		 * Each function is expected to return an array where each element of the
39680		 * array can be one of:
39681		 *
39682		 * * `first` - Jump to first page when activated
39683		 * * `last` - Jump to last page when activated
39684		 * * `previous` - Show previous page when activated
39685		 * * `next` - Show next page when activated
39686		 * * `{int}` - Show page of the index given
39687		 * * `{array}` - A nested array containing the above elements to add a
39688		 *   containing 'DIV' element (might be useful for styling).
39689		 *
39690		 * Note that DataTables v1.9- used this object slightly differently whereby
39691		 * an object with two functions would be defined for each plug-in. That
39692		 * ability is still supported by DataTables 1.10+ to provide backwards
39693		 * compatibility, but this option of use is now decremented and no longer
39694		 * documented in DataTables 1.10+.
39695		 *
39696		 *  @type object
39697		 *  @default {}
39698		 *
39699		 *  @example
39700		 *    // Show previous, next and current page buttons only
39701		 *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
39702		 *      return [ 'previous', page, 'next' ];
39703		 *    };
39704		 */
39705		pager: {},
39706
39707
39708		renderer: {
39709			pageButton: {},
39710			header: {}
39711		},
39712
39713
39714		/**
39715		 * Ordering plug-ins - custom data source
39716		 *
39717		 * The extension options for ordering of data available here is complimentary
39718		 * to the default type based ordering that DataTables typically uses. It
39719		 * allows much greater control over the the data that is being used to
39720		 * order a column, but is necessarily therefore more complex.
39721		 *
39722		 * This type of ordering is useful if you want to do ordering based on data
39723		 * live from the DOM (for example the contents of an 'input' element) rather
39724		 * than just the static string that DataTables knows of.
39725		 *
39726		 * The way these plug-ins work is that you create an array of the values you
39727		 * wish to be ordering for the column in question and then return that
39728		 * array. The data in the array much be in the index order of the rows in
39729		 * the table (not the currently ordering order!). Which order data gathering
39730		 * function is run here depends on the `dt-init columns.orderDataType`
39731		 * parameter that is used for the column (if any).
39732		 *
39733		 * The functions defined take two parameters:
39734		 *
39735		 * 1. `{object}` DataTables settings object: see
39736		 *    {@link DataTable.models.oSettings}
39737		 * 2. `{int}` Target column index
39738		 *
39739		 * Each function is expected to return an array:
39740		 *
39741		 * * `{array}` Data for the column to be ordering upon
39742		 *
39743		 *  @type array
39744		 *
39745		 *  @example
39746		 *    // Ordering using `input` node values
39747		 *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
39748		 *    {
39749		 *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
39750		 *        return $('input', td).val();
39751		 *      } );
39752		 *    }
39753		 */
39754		order: {},
39755
39756
39757		/**
39758		 * Type based plug-ins.
39759		 *
39760		 * Each column in DataTables has a type assigned to it, either by automatic
39761		 * detection or by direct assignment using the `type` option for the column.
39762		 * The type of a column will effect how it is ordering and search (plug-ins
39763		 * can also make use of the column type if required).
39764		 *
39765		 * @namespace
39766		 */
39767		type: {
39768			/**
39769			 * Type detection functions.
39770			 *
39771			 * The functions defined in this object are used to automatically detect
39772			 * a column's type, making initialisation of DataTables super easy, even
39773			 * when complex data is in the table.
39774			 *
39775			 * The functions defined take two parameters:
39776			 *
39777			 *  1. `{*}` Data from the column cell to be analysed
39778			 *  2. `{settings}` DataTables settings object. This can be used to
39779			 *     perform context specific type detection - for example detection
39780			 *     based on language settings such as using a comma for a decimal
39781			 *     place. Generally speaking the options from the settings will not
39782			 *     be required
39783			 *
39784			 * Each function is expected to return:
39785			 *
39786			 * * `{string|null}` Data type detected, or null if unknown (and thus
39787			 *   pass it on to the other type detection functions.
39788			 *
39789			 *  @type array
39790			 *
39791			 *  @example
39792			 *    // Currency type detection plug-in:
39793			 *    $.fn.dataTable.ext.type.detect.push(
39794			 *      function ( data, settings ) {
39795			 *        // Check the numeric part
39796			 *        if ( ! $.isNumeric( data.substring(1) ) ) {
39797			 *          return null;
39798			 *        }
39799			 *
39800			 *        // Check prefixed by currency
39801			 *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
39802			 *          return 'currency';
39803			 *        }
39804			 *        return null;
39805			 *      }
39806			 *    );
39807			 */
39808			detect: [],
39809
39810
39811			/**
39812			 * Type based search formatting.
39813			 *
39814			 * The type based searching functions can be used to pre-format the
39815			 * data to be search on. For example, it can be used to strip HTML
39816			 * tags or to de-format telephone numbers for numeric only searching.
39817			 *
39818			 * Note that is a search is not defined for a column of a given type,
39819			 * no search formatting will be performed.
39820			 *
39821			 * Pre-processing of searching data plug-ins - When you assign the sType
39822			 * for a column (or have it automatically detected for you by DataTables
39823			 * or a type detection plug-in), you will typically be using this for
39824			 * custom sorting, but it can also be used to provide custom searching
39825			 * by allowing you to pre-processing the data and returning the data in
39826			 * the format that should be searched upon. This is done by adding
39827			 * functions this object with a parameter name which matches the sType
39828			 * for that target column. This is the corollary of <i>afnSortData</i>
39829			 * for searching data.
39830			 *
39831			 * The functions defined take a single parameter:
39832			 *
39833			 *  1. `{*}` Data from the column cell to be prepared for searching
39834			 *
39835			 * Each function is expected to return:
39836			 *
39837			 * * `{string|null}` Formatted string that will be used for the searching.
39838			 *
39839			 *  @type object
39840			 *  @default {}
39841			 *
39842			 *  @example
39843			 *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
39844			 *      return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
39845			 *    }
39846			 */
39847			search: {},
39848
39849
39850			/**
39851			 * Type based ordering.
39852			 *
39853			 * The column type tells DataTables what ordering to apply to the table
39854			 * when a column is sorted upon. The order for each type that is defined,
39855			 * is defined by the functions available in this object.
39856			 *
39857			 * Each ordering option can be described by three properties added to
39858			 * this object:
39859			 *
39860			 * * `{type}-pre` - Pre-formatting function
39861			 * * `{type}-asc` - Ascending order function
39862			 * * `{type}-desc` - Descending order function
39863			 *
39864			 * All three can be used together, only `{type}-pre` or only
39865			 * `{type}-asc` and `{type}-desc` together. It is generally recommended
39866			 * that only `{type}-pre` is used, as this provides the optimal
39867			 * implementation in terms of speed, although the others are provided
39868			 * for compatibility with existing Javascript sort functions.
39869			 *
39870			 * `{type}-pre`: Functions defined take a single parameter:
39871			 *
39872			 *  1. `{*}` Data from the column cell to be prepared for ordering
39873			 *
39874			 * And return:
39875			 *
39876			 * * `{*}` Data to be sorted upon
39877			 *
39878			 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
39879			 * functions, taking two parameters:
39880			 *
39881			 *  1. `{*}` Data to compare to the second parameter
39882			 *  2. `{*}` Data to compare to the first parameter
39883			 *
39884			 * And returning:
39885			 *
39886			 * * `{*}` Ordering match: <0 if first parameter should be sorted lower
39887			 *   than the second parameter, ===0 if the two parameters are equal and
39888			 *   >0 if the first parameter should be sorted height than the second
39889			 *   parameter.
39890			 *
39891			 *  @type object
39892			 *  @default {}
39893			 *
39894			 *  @example
39895			 *    // Numeric ordering of formatted numbers with a pre-formatter
39896			 *    $.extend( $.fn.dataTable.ext.type.order, {
39897			 *      "string-pre": function(x) {
39898			 *        a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
39899			 *        return parseFloat( a );
39900			 *      }
39901			 *    } );
39902			 *
39903			 *  @example
39904			 *    // Case-sensitive string ordering, with no pre-formatting method
39905			 *    $.extend( $.fn.dataTable.ext.order, {
39906			 *      "string-case-asc": function(x,y) {
39907			 *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
39908			 *      },
39909			 *      "string-case-desc": function(x,y) {
39910			 *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
39911			 *      }
39912			 *    } );
39913			 */
39914			order: {}
39915		},
39916
39917		/**
39918		 * Unique DataTables instance counter
39919		 *
39920		 * @type int
39921		 * @private
39922		 */
39923		_unique: 0,
39924
39925
39926		//
39927		// Depreciated
39928		// The following properties are retained for backwards compatiblity only.
39929		// The should not be used in new projects and will be removed in a future
39930		// version
39931		//
39932
39933		/**
39934		 * Version check function.
39935		 *  @type function
39936		 *  @depreciated Since 1.10
39937		 */
39938		fnVersionCheck: DataTable.fnVersionCheck,
39939
39940
39941		/**
39942		 * Index for what 'this' index API functions should use
39943		 *  @type int
39944		 *  @deprecated Since v1.10
39945		 */
39946		iApiIndex: 0,
39947
39948
39949		/**
39950		 * jQuery UI class container
39951		 *  @type object
39952		 *  @deprecated Since v1.10
39953		 */
39954		oJUIClasses: {},
39955
39956
39957		/**
39958		 * Software version
39959		 *  @type string
39960		 *  @deprecated Since v1.10
39961		 */
39962		sVersion: DataTable.version
39963	};
39964
39965
39966	//
39967	// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
39968	//
39969	$.extend( _ext, {
39970		afnFiltering: _ext.search,
39971		aTypes:       _ext.type.detect,
39972		ofnSearch:    _ext.type.search,
39973		oSort:        _ext.type.order,
39974		afnSortData:  _ext.order,
39975		aoFeatures:   _ext.feature,
39976		oApi:         _ext.internal,
39977		oStdClasses:  _ext.classes,
39978		oPagination:  _ext.pager
39979	} );
39980
39981
39982	$.extend( DataTable.ext.classes, {
39983		"sTable": "dataTable",
39984		"sNoFooter": "no-footer",
39985
39986		/* Paging buttons */
39987		"sPageButton": "paginate_button",
39988		"sPageButtonActive": "current",
39989		"sPageButtonDisabled": "disabled",
39990
39991		/* Striping classes */
39992		"sStripeOdd": "odd",
39993		"sStripeEven": "even",
39994
39995		/* Empty row */
39996		"sRowEmpty": "dataTables_empty",
39997
39998		/* Features */
39999		"sWrapper": "dataTables_wrapper",
40000		"sFilter": "dataTables_filter",
40001		"sInfo": "dataTables_info",
40002		"sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
40003		"sLength": "dataTables_length",
40004		"sProcessing": "dataTables_processing",
40005
40006		/* Sorting */
40007		"sSortAsc": "sorting_asc",
40008		"sSortDesc": "sorting_desc",
40009		"sSortable": "sorting", /* Sortable in both directions */
40010		"sSortableAsc": "sorting_asc_disabled",
40011		"sSortableDesc": "sorting_desc_disabled",
40012		"sSortableNone": "sorting_disabled",
40013		"sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
40014
40015		/* Filtering */
40016		"sFilterInput": "",
40017
40018		/* Page length */
40019		"sLengthSelect": "",
40020
40021		/* Scrolling */
40022		"sScrollWrapper": "dataTables_scroll",
40023		"sScrollHead": "dataTables_scrollHead",
40024		"sScrollHeadInner": "dataTables_scrollHeadInner",
40025		"sScrollBody": "dataTables_scrollBody",
40026		"sScrollFoot": "dataTables_scrollFoot",
40027		"sScrollFootInner": "dataTables_scrollFootInner",
40028
40029		/* Misc */
40030		"sHeaderTH": "",
40031		"sFooterTH": "",
40032
40033		// Deprecated
40034		"sSortJUIAsc": "",
40035		"sSortJUIDesc": "",
40036		"sSortJUI": "",
40037		"sSortJUIAscAllowed": "",
40038		"sSortJUIDescAllowed": "",
40039		"sSortJUIWrapper": "",
40040		"sSortIcon": "",
40041		"sJUIHeader": "",
40042		"sJUIFooter": ""
40043	} );
40044
40045
40046	(function() {
40047
40048		// Reused strings for better compression. Closure compiler appears to have a
40049		// weird edge case where it is trying to expand strings rather than use the
40050		// variable version. This results in about 200 bytes being added, for very
40051		// little preference benefit since it this run on script load only.
40052		var _empty = '';
40053		_empty = '';
40054
40055		var _stateDefault = _empty + 'ui-state-default';
40056		var _sortIcon     = _empty + 'css_right ui-icon ui-icon-';
40057		var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
40058
40059		$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
40060			/* Full numbers paging buttons */
40061			"sPageButton":         "fg-button ui-button "+_stateDefault,
40062			"sPageButtonActive":   "ui-state-disabled",
40063			"sPageButtonDisabled": "ui-state-disabled",
40064
40065			/* Features */
40066			"sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
40067				"ui-buttonset-multi paging_", /* Note that the type is postfixed */
40068
40069			/* Sorting */
40070			"sSortAsc":            _stateDefault+" sorting_asc",
40071			"sSortDesc":           _stateDefault+" sorting_desc",
40072			"sSortable":           _stateDefault+" sorting",
40073			"sSortableAsc":        _stateDefault+" sorting_asc_disabled",
40074			"sSortableDesc":       _stateDefault+" sorting_desc_disabled",
40075			"sSortableNone":       _stateDefault+" sorting_disabled",
40076			"sSortJUIAsc":         _sortIcon+"triangle-1-n",
40077			"sSortJUIDesc":        _sortIcon+"triangle-1-s",
40078			"sSortJUI":            _sortIcon+"carat-2-n-s",
40079			"sSortJUIAscAllowed":  _sortIcon+"carat-1-n",
40080			"sSortJUIDescAllowed": _sortIcon+"carat-1-s",
40081			"sSortJUIWrapper":     "DataTables_sort_wrapper",
40082			"sSortIcon":           "DataTables_sort_icon",
40083
40084			/* Scrolling */
40085			"sScrollHead": "dataTables_scrollHead "+_stateDefault,
40086			"sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
40087
40088			/* Misc */
40089			"sHeaderTH":  _stateDefault,
40090			"sFooterTH":  _stateDefault,
40091			"sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
40092			"sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
40093		} );
40094
40095	}());
40096
40097
40098
40099	var extPagination = DataTable.ext.pager;
40100
40101	function _numbers ( page, pages ) {
40102		var
40103			numbers = [],
40104			buttons = extPagination.numbers_length,
40105			half = Math.floor( buttons / 2 ),
40106			i = 1;
40107
40108		if ( pages <= buttons ) {
40109			numbers = _range( 0, pages );
40110		}
40111		else if ( page <= half ) {
40112			numbers = _range( 0, buttons-2 );
40113			numbers.push( 'ellipsis' );
40114			numbers.push( pages-1 );
40115		}
40116		else if ( page >= pages - 1 - half ) {
40117			numbers = _range( pages-(buttons-2), pages );
40118			numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
40119			numbers.splice( 0, 0, 0 );
40120		}
40121		else {
40122			numbers = _range( page-half+2, page+half-1 );
40123			numbers.push( 'ellipsis' );
40124			numbers.push( pages-1 );
40125			numbers.splice( 0, 0, 'ellipsis' );
40126			numbers.splice( 0, 0, 0 );
40127		}
40128
40129		numbers.DT_el = 'span';
40130		return numbers;
40131	}
40132
40133
40134	$.extend( extPagination, {
40135		simple: function ( page, pages ) {
40136			return [ 'previous', 'next' ];
40137		},
40138
40139		full: function ( page, pages ) {
40140			return [  'first', 'previous', 'next', 'last' ];
40141		},
40142
40143		numbers: function ( page, pages ) {
40144			return [ _numbers(page, pages) ];
40145		},
40146
40147		simple_numbers: function ( page, pages ) {
40148			return [ 'previous', _numbers(page, pages), 'next' ];
40149		},
40150
40151		full_numbers: function ( page, pages ) {
40152			return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
40153		},
40154
40155		// For testing and plug-ins to use
40156		_numbers: _numbers,
40157
40158		// Number of number buttons (including ellipsis) to show. _Must be odd!_
40159		numbers_length: 7
40160	} );
40161
40162
40163	$.extend( true, DataTable.ext.renderer, {
40164		pageButton: {
40165			_: function ( settings, host, idx, buttons, page, pages ) {
40166				var classes = settings.oClasses;
40167				var lang = settings.oLanguage.oPaginate;
40168				var aria = settings.oLanguage.oAria.paginate || {};
40169				var btnDisplay, btnClass, counter=0;
40170
40171				var attach = function( container, buttons ) {
40172					var i, ien, node, button;
40173					var clickHandler = function ( e ) {
40174						_fnPageChange( settings, e.data.action, true );
40175					};
40176
40177					for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
40178						button = buttons[i];
40179
40180						if ( $.isArray( button ) ) {
40181							var inner = $( '<'+(button.DT_el || 'div')+'/>' )
40182								.appendTo( container );
40183							attach( inner, button );
40184						}
40185						else {
40186							btnDisplay = null;
40187							btnClass = '';
40188
40189							switch ( button ) {
40190								case 'ellipsis':
40191									container.append('<span class="ellipsis">&#x2026;
40191</span>');
40192									break;
40193
40194								case 'first':
40195									btnDisplay = lang.sFirst;
40196									btnClass = button + (page > 0 ?
40197										'' : ' '+classes.sPageButtonDisabled);
40198									break;
40199
40200								case 'previous':
40201									btnDisplay = lang.sPrevious;
40202									btnClass = button + (page > 0 ?
40203										'' : ' '+classes.sPageButtonDisabled);
40204									break;
40205
40206								case 'next':
40207									btnDisplay = lang.sNext;
40208									btnClass = button + (page < pages-1 ?
40209										'' : ' '+classes.sPageButtonDisabled);
40210									break;
40211
40212								case 'last':
40213									btnDisplay = lang.sLast;
40214									btnClass = button + (page < pages-1 ?
40215										'' : ' '+classes.sPageButtonDisabled);
40216									break;
40217
40218								default:
40219									btnDisplay = button + 1;
40220									btnClass = page === button ?
40221										classes.sPageButtonActive : '';
40222									break;
40223							}
40224
40225							if ( btnDisplay !== null ) {
40226								node = $('<a>', {
40227									'class': classes.sPageButton+' '+btnClass,
40228									'aria-controls': settings.sTableId,
40229									'aria-label': aria[ button ],
40230									'data-dt-idx': counter,
40231									'tabindex': settings.iTabIndex,
40232									'id': idx === 0 && typeof button === 'string' ?
40233										settings.sTableId +'_'+ button :
40234										null
40235								} )
40236									.html( btnDisplay )
40237									.appendTo( container );
40238
40239								_fnBindAction(
40240									node, {action: button}, clickHandler
40241								);
40242
40243								counter++;
40244							}
40245						}
40246					}
40247				};
40248
40249				// IE9 throws an 'unknown error' if document.activeElement is used
40250				// inside an iframe or frame. Try / catch the error. Not good for
40251				// accessibility, but neither are frames.
40252				var activeEl;
40253
40254				try {
40255					// Because this approach is destroying and recreating the paging
40256					// elements, focus is lost on the select button which is bad for
40257					// accessibility. So we want to restore focus once the draw has
40258					// completed
40259					activeEl = $(host).find(document.activeElement).data('dt-idx');
40260				}
40261				catch (e) {}
40262
40263				attach( $(host).empty(), buttons );
40264
40265				if ( activeEl ) {
40266					$(host).find( '[data-dt-idx='+activeEl+']' ).focus();
40267				}
40268			}
40269		}
40270	} );
40271
40272
40273
40274	// Built in type detection. See model.ext.aTypes for information about
40275	// what is required from this methods.
40276	$.extend( DataTable.ext.type.detect, [
40277		// Plain numbers - first since V8 detects some plain numbers as dates
40278		// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
40279		function ( d, settings )
40280		{
40281			var decimal = settings.oLanguage.sDecimal;
40282			return _isNumber( d, decimal ) ? 'num'+decimal : null;
40283		},
40284
40285		// Dates (only those recognised by the browser's Date.parse)
40286		function ( d, settings )
40287		{
40288			// V8 will remove any unknown characters at the start and end of the
40289			// expression, leading to false matches such as `$245.12` or `10%` being
40290			// a valid date. See forum thread 18941 for detail.
40291			if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
40292				return null;
40293			}
40294			var parsed = Date.parse(d);
40295			return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
40296		},
40297
40298		// Formatted numbers
40299		function ( d, settings )
40300		{
40301			var decimal = settings.oLanguage.sDecimal;
40302			return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
40303		},
40304
40305		// HTML numeric
40306		function ( d, settings )
40307		{
40308			var decimal = settings.oLanguage.sDecimal;
40309			return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
40310		},
40311
40312		// HTML numeric, formatted
40313		function ( d, settings )
40314		{
40315			var decimal = settings.oLanguage.sDecimal;
40316			return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
40317		},
40318
40319		// HTML (this is strict checking - there must be html)
40320		function ( d, settings )
40321		{
40322			return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
40323				'html' : null;
40324		}
40325	] );
40326
40327
40328
40329	// Filter formatting functions. See model.ext.ofnSearch for information about
40330	// what is required from these methods.
40331	//
40332	// Note that additional search methods are added for the html numbers and
40333	// html formatted numbers by `_addNumericSort()` when we know what the decimal
40334	// place is
40335
40336
40337	$.extend( DataTable.ext.type.search, {
40338		html: function ( data ) {
40339			return _empty(data) ?
40340				data :
40341				typeof data === 'string' ?
40342					data
40343						.replace( _re_new_lines, " " )
40344						.replace( _re_html, "" ) :
40345					'';
40346		},
40347
40348		string: function ( data ) {
40349			return _empty(data) ?
40350				data :
40351				typeof data === 'string' ?
40352					data.replace( _re_new_lines, " " ) :
40353					data;
40354		}
40355	} );
40356
40357
40358
40359	var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
40360		if ( d !== 0 && (!d || d === '-') ) {
40361			return -Infinity;
40362		}
40363
40364		// If a decimal place other than `.` is used, it needs to be given to the
40365		// function so we can detect it and replace with a `.` which is the only
40366		// decimal place Javascript recognises - it is not locale aware.
40367		if ( decimalPlace ) {
40368			d = _numToDecimal( d, decimalPlace );
40369		}
40370
40371		if ( d.replace ) {
40372			if ( re1 ) {
40373				d = d.replace( re1, '' );
40374			}
40375
40376			if ( re2 ) {
40377				d = d.replace( re2, '' );
40378			}
40379		}
40380
40381		return d * 1;
40382	};
40383
40384
40385	// Add the numeric 'deformatting' functions for sorting and search. This is done
40386	// in a function to provide an easy ability for the language options to add
40387	// additional methods if a non-period decimal place is used.
40388	function _addNumericSort ( decimalPlace ) {
40389		$.each(
40390			{
40391				// Plain numbers
40392				"num": function ( d ) {
40393					return __numericReplace( d, decimalPlace );
40394				},
40395
40396				// Formatted numbers
40397				"num-fmt": function ( d ) {
40398					return __numericReplace( d, decimalPlace, _re_formatted_numeric );
40399				},
40400
40401				// HTML numeric
40402				"html-num": function ( d ) {
40403					return __numericReplace( d, decimalPlace, _re_html );
40404				},
40405
40406				// HTML numeric, formatted
40407				"html-num-fmt": function ( d ) {
40408					return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
40409				}
40410			},
40411			function ( key, fn ) {
40412				// Add the ordering method
40413				_ext.type.order[ key+decimalPlace+'-pre' ] = fn;
40414
40415				// For HTML types add a search formatter that will strip the HTML
40416				if ( key.match(/^html\-/) ) {
40417					_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
40418				}
40419			}
40420		);
40421	}
40422
40423
40424	// Default sort methods
40425	$.extend( _ext.type.order, {
40426		// Dates
40427		"date-pre": function ( d ) {
40428			return Date.parse( d ) || 0;
40429		},
40430
40431		// html
40432		"html-pre": function ( a ) {
40433			return _empty(a) ?
40434				'' :
40435				a.replace ?
40436					a.replace( /<.*?>/g, "" ).toLowerCase() :
40437					a+'';
40438		},
40439
40440		// string
40441		"string-pre": function ( a ) {
40442			// This is a little complex, but faster than always calling toString,
40443			// http://jsperf.com/tostring-v-check
40444			return _empty(a) ?
40445				'' :
40446				typeof a === 'string' ?
40447					a.toLowerCase() :
40448					! a.toString ?
40449						'' :
40450						a.toString();
40451		},
40452
40453		// string-asc and -desc are retained only for compatibility with the old
40454		// sort methods
40455		"string-asc": function ( x, y ) {
40456			return ((x < y) ? -1 : ((x > y) ? 1 : 0));
40457		},
40458
40459		"string-desc": function ( x, y ) {
40460			return ((x < y) ? 1 : ((x > y) ? -1 : 0));
40461		}
40462	} );
40463
40464
40465	// Numeric sorting types - order doesn't matter here
40466	_addNumericSort( '' );
40467
40468
40469	$.extend( true, DataTable.ext.renderer, {
40470		header: {
40471			_: function ( settings, cell, column, classes ) {
40472				// No additional mark-up required
vendor: 13,058 bytes, lines 40473-40870
40473				// Attach a sort listener to update on sort - note that using the
40474				// `DT` namespace will allow the event to be removed automatically
40475				// on destroy, while the `dt` namespaced event is the one we are
40476				// listening for
40477				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
40478					if ( settings !== ctx ) { // need to check this this is the host
40479						return;               // table, not a nested one
40480					}
40481
40482					var colIdx = column.idx;
40483
40484					cell
40485						.removeClass(
40486							column.sSortingClass +' '+
40487							classes.sSortAsc +' '+
40488							classes.sSortDesc
40489						)
40490						.addClass( columns[ colIdx ] == 'asc' ?
40491							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
40492								classes.sSortDesc :
40493								column.sSortingClass
40494						);
40495				} );
40496			},
40497
40498			jqueryui: function ( settings, cell, column, classes ) {
40499				$('<div/>')
40500					.addClass( classes.sSortJUIWrapper )
40501					.append( cell.contents() )
40502					.append( $('<span/>')
40503						.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
40504					)
40505					.appendTo( cell );
40506
40507				// Attach a sort listener to update on sort
40508				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
40509					if ( settings !== ctx ) {
40510						return;
40511					}
40512
40513					var colIdx = column.idx;
40514
40515					cell
40516						.removeClass( classes.sSortAsc +" "+classes.sSortDesc )
40517						.addClass( columns[ colIdx ] == 'asc' ?
40518							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
40519								classes.sSortDesc :
40520								column.sSortingClass
40521						);
40522
40523					cell
40524						.find( 'span.'+classes.sSortIcon )
40525						.removeClass(
40526							classes.sSortJUIAsc +" "+
40527							classes.sSortJUIDesc +" "+
40528							classes.sSortJUI +" "+
40529							classes.sSortJUIAscAllowed +" "+
40530							classes.sSortJUIDescAllowed
40531						)
40532						.addClass( columns[ colIdx ] == 'asc' ?
40533							classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
40534								classes.sSortJUIDesc :
40535								column.sSortingClassJUI
40536						);
40537				} );
40538			}
40539		}
40540	} );
40541
40542	/*
40543	 * Public helper functions. These aren't used internally by DataTables, or
40544	 * called by any of the options passed into DataTables, but they can be used
40545	 * externally by developers working with DataTables. They are helper functions
40546	 * to make working with DataTables a little bit easier.
40547	 */
40548
40549	var __htmlEscapeEntities = function ( d ) {
40550		return typeof d === 'string' ?
40551			d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
40552			d;
40553	};
40554
40555	/**
40556	 * Helpers for `columns.render`.
40557	 *
40558	 * The options defined here can be used with the `columns.render` initialisation
40559	 * option to provide a display renderer. The following functions are defined:
40560	 *
40561	 * * `number` - Will format numeric data (defined by `columns.data`) for
40562	 *   display, retaining the original unformatted data for sorting and filtering.
40563	 *   It takes 5 parameters:
40564	 *   * `string` - Thousands grouping separator
40565	 *   * `string` - Decimal point indicator
40566	 *   * `integer` - Number of decimal points to show
40567	 *   * `string` (optional) - Prefix.
40568	 *   * `string` (optional) - Postfix (/suffix).
40569	 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
40570	 *   parameters.
40571	 *
40572	 * @example
40573	 *   // Column definition using the number renderer
40574	 *   {
40575	 *     data: "salary",
40576	 *     render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
40577	 *   }
40578	 *
40579	 * @namespace
40580	 */
40581	DataTable.render = {
40582		number: function ( thousands, decimal, precision, prefix, postfix ) {
40583			return {
40584				display: function ( d ) {
40585					if ( typeof d !== 'number' && typeof d !== 'string' ) {
40586						return d;
40587					}
40588
40589					var negative = d < 0 ? '-' : '';
40590					var flo = parseFloat( d );
40591
40592					// If NaN then there isn't much formatting that we can do - just
40593					// return immediately, escaping any HTML (this was supposed to
40594					// be a number after all)
40595					if ( isNaN( flo ) ) {
40596						return __htmlEscapeEntities( d );
40597					}
40598
40599					d = Math.abs( flo );
40600
40601					var intPart = parseInt( d, 10 );
40602					var floatPart = precision ?
40603						decimal+(d - intPart).toFixed( precision ).substring( 2 ):
40604						'';
40605
40606					return negative + (prefix||'') +
40607						intPart.toString().replace(
40608							/\B(?=(\d{3})+(?!\d))/g, thousands
40609						) +
40610						floatPart +
40611						(postfix||'');
40612				}
40613			};
40614		},
40615
40616		text: function () {
40617			return {
40618				display: __htmlEscapeEntities
40619			};
40620		}
40621	};
40622
40623
40624	/*
40625	 * This is really a good bit rubbish this method of exposing the internal methods
40626	 * publicly... - To be fixed in 2.0 using methods on the prototype
40627	 */
40628
40629
40630	/**
40631	 * Create a wrapper function for exporting an internal functions to an external API.
40632	 *  @param {string} fn API function name
40633	 *  @returns {function} wrapped function
40634	 *  @memberof DataTable#internal
40635	 */
40636	function _fnExternApiFunc (fn)
40637	{
40638		return function() {
40639			var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
40640				Array.prototype.slice.call(arguments)
40641			);
40642			return DataTable.ext.internal[fn].apply( this, args );
40643		};
40644	}
40645
40646
40647	/**
40648	 * Reference to internal functions for use by plug-in developers. Note that
40649	 * these methods are references to internal functions and are considered to be
40650	 * private. If you use these methods, be aware that they are liable to change
40651	 * between versions.
40652	 *  @namespace
40653	 */
40654	$.extend( DataTable.ext.internal, {
40655		_fnExternApiFunc: _fnExternApiFunc,
40656		_fnBuildAjax: _fnBuildAjax,
40657		_fnAjaxUpdate: _fnAjaxUpdate,
40658		_fnAjaxParameters: _fnAjaxParameters,
40659		_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
40660		_fnAjaxDataSrc: _fnAjaxDataSrc,
40661		_fnAddColumn: _fnAddColumn,
40662		_fnColumnOptions: _fnColumnOptions,
40663		_fnAdjustColumnSizing: _fnAdjustColumnSizing,
40664		_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
40665		_fnColumnIndexToVisible: _fnColumnIndexToVisible,
40666		_fnVisbleColumns: _fnVisbleColumns,
40667		_fnGetColumns: _fnGetColumns,
40668		_fnColumnTypes: _fnColumnTypes,
40669		_fnApplyColumnDefs: _fnApplyColumnDefs,
40670		_fnHungarianMap: _fnHungarianMap,
40671		_fnCamelToHungarian: _fnCamelToHungarian,
40672		_fnLanguageCompat: _fnLanguageCompat,
40673		_fnBrowserDetect: _fnBrowserDetect,
40674		_fnAddData: _fnAddData,
40675		_fnAddTr: _fnAddTr,
40676		_fnNodeToDataIndex: _fnNodeToDataIndex,
40677		_fnNodeToColumnIndex: _fnNodeToColumnIndex,
40678		_fnGetCellData: _fnGetCellData,
40679		_fnSetCellData: _fnSetCellData,
40680		_fnSplitObjNotation: _fnSplitObjNotation,
40681		_fnGetObjectDataFn: _fnGetObjectDataFn,
40682		_fnSetObjectDataFn: _fnSetObjectDataFn,
40683		_fnGetDataMaster: _fnGetDataMaster,
40684		_fnClearTable: _fnClearTable,
40685		_fnDeleteIndex: _fnDeleteIndex,
40686		_fnInvalidate: _fnInvalidate,
40687		_fnGetRowElements: _fnGetRowElements,
40688		_fnCreateTr: _fnCreateTr,
40689		_fnBuildHead: _fnBuildHead,
40690		_fnDrawHead: _fnDrawHead,
40691		_fnDraw: _fnDraw,
40692		_fnReDraw: _fnReDraw,
40693		_fnAddOptionsHtml: _fnAddOptionsHtml,
40694		_fnDetectHeader: _fnDetectHeader,
40695		_fnGetUniqueThs: _fnGetUniqueThs,
40696		_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
40697		_fnFilterComplete: _fnFilterComplete,
40698		_fnFilterCustom: _fnFilterCustom,
40699		_fnFilterColumn: _fnFilterColumn,
40700		_fnFilter: _fnFilter,
40701		_fnFilterCreateSearch: _fnFilterCreateSearch,
40702		_fnEscapeRegex: _fnEscapeRegex,
40703		_fnFilterData: _fnFilterData,
40704		_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
40705		_fnUpdateInfo: _fnUpdateInfo,
40706		_fnInfoMacros: _fnInfoMacros,
40707		_fnInitialise: _fnInitialise,
40708		_fnInitComplete: _fnInitComplete,
40709		_fnLengthChange: _fnLengthChange,
40710		_fnFeatureHtmlLength: _fnFeatureHtmlLength,
40711		_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
40712		_fnPageChange: _fnPageChange,
40713		_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
40714		_fnProcessingDisplay: _fnProcessingDisplay,
40715		_fnFeatureHtmlTable: _fnFeatureHtmlTable,
40716		_fnScrollDraw: _fnScrollDraw,
40717		_fnApplyToChildren: _fnApplyToChildren,
40718		_fnCalculateColumnWidths: _fnCalculateColumnWidths,
40719		_fnThrottle: _fnThrottle,
40720		_fnConvertToWidth: _fnConvertToWidth,
40721		_fnGetWidestNode: _fnGetWidestNode,
40722		_fnGetMaxLenString: _fnGetMaxLenString,
40723		_fnStringToCss: _fnStringToCss,
40724		_fnSortFlatten: _fnSortFlatten,
40725		_fnSort: _fnSort,
40726		_fnSortAria: _fnSortAria,
40727		_fnSortListener: _fnSortListener,
40728		_fnSortAttachListener: _fnSortAttachListener,
40729		_fnSortingClasses: _fnSortingClasses,
40730		_fnSortData: _fnSortData,
40731		_fnSaveState: _fnSaveState,
40732		_fnLoadState: _fnLoadState,
40733		_fnSettingsFromNode: _fnSettingsFromNode,
40734		_fnLog: _fnLog,
40735		_fnMap: _fnMap,
40736		_fnBindAction: _fnBindAction,
40737		_fnCallbackReg: _fnCallbackReg,
40738		_fnCallbackFire: _fnCallbackFire,
40739		_fnLengthOverflow: _fnLengthOverflow,
40740		_fnRenderer: _fnRenderer,
40741		_fnDataSource: _fnDataSource,
40742		_fnRowAttributes: _fnRowAttributes,
40743		_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
40744										// in 1.10, so this dead-end function is
40745										// added to prevent errors
40746	} );
40747
40748
40749	// jQuery access
40750	$.fn.dataTable = DataTable;
40751
40752	// Provide access to the host jQuery object (circular reference)
40753	DataTable.$ = $;
40754
40755	// Legacy aliases
40756	$.fn.dataTableSettings = DataTable.settings;
40757	$.fn.dataTableExt = DataTable.ext;
40758
40759	// With a capital `D` we return a DataTables API instance rather than a
40760	// jQuery object
40761	$.fn.DataTable = function ( opts ) {
40762		return $(this).dataTable( opts ).api();
40763	};
40764
40765	// All properties that are available to $.fn.dataTable should also be
40766	// available on $.fn.DataTable
40767	$.each( DataTable, function ( prop, val ) {
40768		$.fn.DataTable[ prop ] = val;
40769	} );
40770
40771
40772	// Information about events fired by DataTables - for documentation.
40773	/**
40774	 * Draw event, fired whenever the table is redrawn on the page, at the same
40775	 * point as fnDrawCallback. This may be useful for binding events or
40776	 * performing calculations when the table is altered at all.
40777	 *  @name DataTable#draw.dt
40778	 *  @event
40779	 *  @param {event} e jQuery event object
40780	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40781	 */
40782
40783	/**
40784	 * Search event, fired when the searching applied to the table (using the
40785	 * built-in global search, or column filters) is altered.
40786	 *  @name DataTable#search.dt
40787	 *  @event
40788	 *  @param {event} e jQuery event object
40789	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40790	 */
40791
40792	/**
40793	 * Page change event, fired when the paging of the table is altered.
40794	 *  @name DataTable#page.dt
40795	 *  @event
40796	 *  @param {event} e jQuery event object
40797	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40798	 */
40799
40800	/**
40801	 * Order event, fired when the ordering applied to the table is altered.
40802	 *  @name DataTable#order.dt
40803	 *  @event
40804	 *  @param {event} e jQuery event object
40805	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40806	 */
40807
40808	/**
40809	 * DataTables initialisation complete event, fired when the table is fully
40810	 * drawn, including Ajax data loaded, if Ajax data is required.
40811	 *  @name DataTable#init.dt
40812	 *  @event
40813	 *  @param {event} e jQuery event object
40814	 *  @param {object} oSettings DataTables settings object
40815	 *  @param {object} json The JSON object request from the server - only
40816	 *    present if client-side Ajax sourced data is used</li></ol>
40817	 */
40818
40819	/**
40820	 * State save event, fired when the table has changed state a new state save
40821	 * is required. This event allows modification of the state saving object
40822	 * prior to actually doing the save, including addition or other state
40823	 * properties (for plug-ins) or modification of a DataTables core property.
40824	 *  @name DataTable#stateSaveParams.dt
40825	 *  @event
40826	 *  @param {event} e jQuery event object
40827	 *  @param {object} oSettings DataTables settings object
40828	 *  @param {object} json The state information to be saved
40829	 */
40830
40831	/**
40832	 * State load event, fired when the table is loading state from the stored
40833	 * data, but prior to the settings object being modified by the saved state
40834	 * - allowing modification of the saved state is required or loading of
40835	 * state for a plug-in.
40836	 *  @name DataTable#stateLoadParams.dt
40837	 *  @event
40838	 *  @param {event} e jQuery event object
40839	 *  @param {object} oSettings DataTables settings object
40840	 *  @param {object} json The saved state information
40841	 */
40842
40843	/**
40844	 * State loaded event, fired when state has been loaded from stored data and
40845	 * the settings object has been modified by the loaded data.
40846	 *  @name DataTable#stateLoaded.dt
40847	 *  @event
40848	 *  @param {event} e jQuery event object
40849	 *  @param {object} oSettings DataTables settings object
40850	 *  @param {object} json The saved state information
40851	 */
40852
40853	/**
40854	 * Processing event, fired when DataTables is doing some kind of processing
40855	 * (be it, order, searcg or anything else). It can be used to indicate to
40856	 * the end user that there is something happening, or that something has
40857	 * finished.
40858	 *  @name DataTable#processing.dt
40859	 *  @event
40860	 *  @param {event} e jQuery event object
40861	 *  @param {object} oSettings DataTables settings object
40862	 *  @param {boolean} bShow Flag for if DataTables is doing processing or not
40863	 */
40864
40865	/**
40866	 * Ajax (XHR) event, fired whenever an Ajax request is completed from a
40867	 * request to made to the server for new data. This event is called before
40868	 * DataTables processed the returned data, so it can also be used to pre-
40869	 * process the data returned from the server, if needed.
40870	 *
40871	 * Note that this trigger is called in `fnServerData`, if you override
40872	 * `fnServerData` and which to use this event, you need to trigger it in you
40873	 * success function.
40874	 *  @name DataTable#xhr.dt
40875	 *  @event
40876	 *  @param {event} e jQuery event object
40877	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40878	 *  @param {object} json JSON returned from the server
40879	 *
40880	 *  @example
40881	 *     // Use a custom property returned from the server in another DOM element
40882	 *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
40883	 *       $('#status').html( json.status );
40884	 *     } );
40885	 *
40886	 *  @example
40887	 *     // Pre-process the data returned from the server
40888	 *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
40889	 *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
40890	 *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
40891	 *       }
40892	 *       // Note no return - manipulate the data directly in the JSON object.
40893	 *     } );
40894	 */
40895
40896	/**
40897	 * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
40898	 * or passing the bDestroy:true parameter in the initialisation object. This
40899	 * can be used to remove bound events, added DOM nodes, etc.
40900	 *  @name DataTable#destroy.dt
40901	 *  @event
40902	 *  @param {event} e jQuery event object
40903	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40904	 */
40905
40906	/**
40907	 * Page length change event, fired when number of records to show on each
40908	 * page (the length) is changed.
40909	 *  @name DataTable#length.dt
40910	 *  @event
40911	 *  @param {event} e jQuery event object
40912	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40913	 *  @param {integer} len New length
40914	 */
40915
40916	/**
40917	 * Column sizing has changed.
40918	 *  @name DataTable#column-sizing.dt
40919	 *  @event
40920	 *  @param {event} e jQuery event object
40921	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40922	 */
40923
40924	/**
40925	 * Column visibility has changed.
40926	 *  @name DataTable#column-visibility.dt
40927	 *  @event
40928	 *  @param {event} e jQuery event object
40929	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
40930	 *  @param {int} column Column index
40931	 *  @param {bool} vis `false` if column now hidden, or `true` if visible
40932	 */
40933
40934	return $.fn.dataTable;
40935}));
40936
40937/*! DataTables Bootstrap 4 integration
40938 * ©2011-2017 SpryMedia Ltd - datatables.net/license
40939 */
40940
40941(function( factory ){
40942	if ( typeof define === 'function' && define.amd ) {
40943		// AMD
40944		define( ['jquery', 'datatables.net'], function ( $ ) {
40945			return factory( $, window, document );
40946		} );
40947	}
40948	else if ( typeof exports === 'object' ) {
40949		// CommonJS
40950		module.exports = function (root, $) {
40951			if ( ! root ) {
40952				// CommonJS environments without a window global must pass a
40953				// root. This will give an error otherwise
40954				root = window;
40955			}
40956
40957			if ( ! $ ) {
40958				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
40959					require('jquery') :
40960					require('jquery')( root );
40961			}
40962
40963			if ( ! $.fn.dataTable ) {
40964				require('datatables.net')(root, $);
40965			}
40966
40967
40968			return factory( $, root, root.document );
40969		};
40970	}
40971	else {
40972		// Browser
40973		factory( jQuery, window, document );
40974	}
40975}(function( $, window, document, undefined ) {
40976	'use strict';
40977	var DataTable = $.fn.dataTable;
40978
40979
40980
40981	/**
40982	 * DataTables integration for Bootstrap 4. This requires Bootstrap 4 and
40983	 * DataTables 1.10 or newer.
40984	 *
40985	 * This file sets the defaults and adds options to DataTables to style its
40986	 * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
40987	 * for further information.
40988	 */
40989
40990	/* Set the defaults for DataTables initialisation */
40991	$.extend( true, DataTable.defaults, {
40992		dom:
40993			"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>>" +
40994			"<'row'<'col-sm-12'tr>>" +
40995			"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
40996		renderer: 'bootstrap'
40997	} );
40998
40999
41000	/* Default class modification */
41001	$.extend( DataTable.ext.classes, {
41002		sWrapper:      "dataTables_wrapper dt-bootstrap4",
41003		sFilterInput:  "form-control form-control-sm",
41004		sLengthSelect: "custom-select custom-select-sm form-control form-control-sm",
41005		sProcessing:   "dataTables_processing card",
41006		sPageButton:   "paginate_button page-item"
41007	} );
41008
41009	$(window).on('load resize', () => {
41010		let $landingPaginationTable = $('#products-table');
41011		let windowWidth = document.documentElement.clientWidth;
41012		if (windowWidth < 400 && $.fn.DataTable.ext.pager.numbers_length != 5) {
41013			$.fn.DataTable.ext.pager.numbers_length = 5;
41014			$landingPaginationTable.DataTable().draw('page');
41015		}
41016		if (windowWidth > 400 && $.fn.DataTable.ext.pager.numbers_length === 5) {
41017			$.fn.DataTable.ext.pager.numbers_length = 7;
41018			$landingPaginationTable.DataTable().draw('page');
41019		}
41020	});
41021
41022	/* Bootstrap paging button renderer */
41023	DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
41024		var api     = new DataTable.Api( settings );
41025		var classes = settings.oClasses;
41026		var lang    = settings.oLanguage.oPaginate;
41027		var aria = settings.oLanguage.oAria.paginate || {};
41028		var btnDisplay, btnClass;
41029
41030		var attach = function( container, buttons ) {
41031			var i, ien, node, button;
41032			var clickHandler = function ( e ) {
41033				e.preventDefault();
41034				if ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {
41035					api.page( e.data.action ).draw( 'page' );
41036				}
41037			};
41038
41039			for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
41040				button = buttons[i];
41041
41042				if ( Array.isArray( button ) ) {
41043					attach( container, button );
41044				}
41045				else {
41046					btnDisplay = '';
41047					btnClass = '';
41048
41049					switch ( button ) {
41050						case 'ellipsis':
41051							btnDisplay = '&#x2026;';
41052							btnClass = 'disabled';
41053							break;
41054
41055						case 'first':
41056							btnDisplay = lang.sFirst;
41057							btnClass = button + (page > 0 ?
41058								'' : ' disabled');
41059							break;
41060
41061						case 'previous':
41062							btnDisplay = lang.sPrevious;
41063							btnClass = button + (page > 0 ?
41064								'' : ' disabled');
41065							break;
41066
41067						case 'next':
41068							btnDisplay = lang.sNext;
41069							btnClass = button + (page < pages-1 ?
41070								'' : ' disabled');
41071							break;
41072
41073						case 'last':
41074							btnDisplay = lang.sLast;
41075							btnClass = button + (page < pages-1 ?
41076								'' : ' disabled');
41077							break;
41078
41079						default:
41080							btnDisplay = button + 1;
41081							btnClass = page === button ?
41082								'active' : '';
41083							break;
41084					}
41085
41086					if ( btnDisplay ) {
41087						node = $('<li>', {
41088							'class': classes.sPageButton+' '+btnClass,
41089							'id': idx === 0 && typeof button === 'string' ?
41090								settings.sTableId +'_'+ button :
41091								null
41092						} )
41093							.append( $('<a>', {
41094									'href': '#',
41095									'aria-controls': settings.sTableId,
41096									'aria-label': aria[ button ],
41097									'data-dt-idx': button,
41098									'tabindex': settings.iTabIndex,
41099									'class': 'page-link'
41100								} )
41101									.html( btnDisplay )
41102							)
41103							.appendTo( container );
41104
41105						settings.oApi._fnBindAction(
41106							node, {action: button}, clickHandler
41107						);
41108					}
41109				}
41110			}
41111		};
41112
41113		// IE9 throws an 'unknown error' if document.activeElement is used
41114		// inside an iframe or frame.
41115		var activeEl;
41116
41117		try {
41118			// Because this approach is destroying and recreating the paging
41119			// elements, focus is lost on the select button which is bad for
41120			// accessibility. So we want to restore focus once the draw has
41121			// completed
41122			activeEl = $(host).find(document.activeElement).data('dt-idx');
41123		}
41124		catch (e) {}
41125
41126		attach(
41127			$(host).empty().html('<ul class="pagination"/>').children('ul'),
41128			buttons
41129		);
41130
41131		if ( activeEl !== undefined ) {
41132			$(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus');
41133		}
41134	};
41135
41136
41137	return DataTable;
41138}));
41139
41140/**
41141 * Bootstrap Multiselect (https://github.com/davidstutz/bootstrap-multiselect)
41142 *
41143 * Apache License, Version 2.0:
41144 * Copyright (c) 2012 - 2015 David Stutz
41145 *
41146 * Licensed under the Apache License, Version 2.0 (the "License");
41146 you may not
41147 * use this file except in compliance with the License. You may obtain a
41148 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0
41149 *
41150 * Unless required by applicable law or agreed to in writing, software
41151 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
41152 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
41153 * License for the specific language governing permissions and limitations
41154 * under the License.
41155 *
41156 * BSD 3-Clause License:
41157 * Copyright (c) 2012 - 2015 David Stutz
41158 * All rights reserved.
41159 *
41160 * Redistribution and use in source and binary forms, with or without
41161 * modification, are permitted provided that the following conditions are met:
41162 *    - Redistributions of source code must retain the above copyright notice,
41163 *      this list of conditions and the following disclaimer.
41164 *    - Redistributions in binary form must reproduce the above copyright notice,
41165 *      this list of conditions and the following disclaimer in the documentation
41166 *      and/or other materials provided with the distribution.
41167 *    - Neither the name of David Stutz nor the names of its contributors may be
41168 *      used to endorse or promote products derived from this software without
41169 *      specific prior written permission.
41170 *
41171 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41172 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
41173 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41174 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
41175 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41176 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41177 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
41178 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41179 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
41180 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41181 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41182 */
41183!function ($) {
41184	"use strict";// jshint ;_;
41185
41186	if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
41187		ko.bindingHandlers.multiselect = {
41188			after: ['options', 'value', 'selectedOptions'],
41189
41190			init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
41191				var $element = $(element);
41192				var config = ko.toJS(valueAccessor());
41193
41194				$element.multiselect(config);
41195
41196				if (allBindings.has('options')) {
41197					var options = allBindings.get('options');
41198					if (ko.isObservable(options)) {
41199						ko.computed({
41200							read: function() {
41201								options();
41202								setTimeout(function() {
41203									var ms = $element.data('multiselect');
41204									if (ms)
41205										ms.updateOriginalOptions();//Not sure how beneficial this is.
41206									$element.multiselect('rebuild');
41207								}, 1);
41208							},
41209							disposeWhenNodeIsRemoved: element
41210						});
41211					}
41212				}
41213
41214				//value and selectedOptions are two-way, so these will be triggered even by our own actions.
41215				//It needs some way to tell if they are triggered because of us or because of outside change.
41216				//It doesn't loop but it's a waste of processing.
41217				if (allBindings.has('value')) {
41218					var value = allBindings.get('value');
41219					if (ko.isObservable(value)) {
41220						ko.computed({
41221							read: function() {
41222								value();
41223								setTimeout(function() {
41224									$element.multiselect('refresh');
41225								}, 1);
41226							},
41227							disposeWhenNodeIsRemoved: element
41228						}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
41229					}
41230				}
41231
41232				//Switched from arrayChange subscription to general subscription using 'refresh'.
41233				//Not sure performance is any better using 'select' and 'deselect'.
41234				if (allBindings.has('selectedOptions')) {
41235					var selectedOptions = allBindings.get('selectedOptions');
41236					if (ko.isObservable(selectedOptions)) {
41237						ko.computed({
41238							read: function() {
41239								selectedOptions();
41240								setTimeout(function() {
41241									$element.multiselect('refresh');
41242								}, 1);
41243							},
41244							disposeWhenNodeIsRemoved: element
41245						}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
41246					}
41247				}
41248
41249				ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
41250					$element.multiselect('destroy');
41251				});
41252			},
41253
41254			update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
41255				var $element = $(element);
41256				var config = ko.toJS(valueAccessor());
41257
41258				$element.multiselect('setOptions', config);
41259				$element.multiselect('rebuild');
41260			}
41261		};
41262	}
41263
41264	function forEach(array, callback) {
41265		for (var index = 0; index < array.length; ++index) {
41266			callback(array[index], index);
41267		}
41268	}
41269
41270	/**
41271	 * Constructor to create a new multiselect using the given select.
41272	 *
41273	 * @param {jQuery} select
41274	 * @param {Object} options
41275	 * @returns {Multiselect}
41276	 */
41277	function Multiselect(select, options) {
41278
41279		this.$select = $(select);
41280
41281		// Placeholder via data attributes
41282		if (this.$select.attr("data-placeholder")) {
41283			options.nonSelectedText = this.$select.data("placeholder");
41284		}
41285
41286		this.options = this.mergeOptions($.extend({}, options, this.$select.data()));
41287
41288		// Initialization.
41289		// We have to clone to create a new reference.
41290		this.originalOptions = this.$select.clone()[0].options;
41291		this.query = '';
41292		this.searchTimeout = null;
41293		this.lastToggledInput = null
41294
41295		this.options.multiple = this.$select.attr('multiple') === "multiple";
41296		this.options.onChange = $.proxy(this.options.onChange, this);
41297		this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this);
41298		this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this);
41299		this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this);
41300		this.options.onDropdownHidden = $.proxy(this.options.onDropdownHidden, this);
41301
41302		// Build select all if enabled.
41303		this.buildContainer();
41304		this.buildButton();
41305		this.buildDropdown();
41306		this.buildSelectAll();
41307		this.buildDropdownOptions();
41308		this.buildFilter();
41309
41310		this.updateButtonText();
41311		this.updateSelectAll();
41312
41313		if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) {
41314			this.disable();
41315		}
41316
41317		this.$select.hide().after(this.$container);
41318	};
41319
41320	Multiselect.prototype = {
41321
41322		defaults: {
41323			/**
41324			 * Default text function will either print 'None selected' in case no
41325			 * option is selected or a list of the selected options up to a length
41326			 * of 3 selected options.
41327			 *
41328			 * @param {jQuery} options
41329			 * @param {jQuery} select
41330			 * @returns {String}
41331			 */
41332			buttonText: function(options, select) {
41333				if (options.length === 0) {
41334					return this.nonSelectedText;
41335				}
41336				else if (this.allSelectedText
41337					&& options.length === $('option', $(select)).length
41338					&& $('option', $(select)).length !== 1
41339					&& this.multiple) {
41340
41341					if (this.selectAllNumber) {
41342						return this.allSelectedText + ' (' + options.length + ')';
41343					}
41344					else {
41345						return this.allSelectedText;
41346					}
41347				}
41348				else if (options.length > this.numberDisplayed) {
41349					return options.length + ' ' + this.nSelectedText;
41350				}
41351				else {
41352					var selected = '';
41353					var delimiter = this.delimiterText;
41354
41355					options.each(function() {
41356						var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text();
41357						selected += label + delimiter;
41358					});
41359
41360					return selected.substr(0, selected.length - 2);
41361				}
41362			},
41363			/**
41364			 * Updates the title of the button similar to the buttonText function.
41365			 *
41366			 * @param {jQuery} options
41367			 * @param {jQuery} select
41368			 * @returns {@exp;selected@call;substr}
41369			 */
41370			buttonTitle: function(options, select) {
41371				if (options.length === 0) {
41372					return this.nonSelectedText;
41373				}
41374				else {
41375					var selected = '';
41376					var delimiter = this.delimiterText;
41377
41378					options.each(function () {
41379						var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text();
41380						selected += label + delimiter;
41381					});
41382					return selected.substr(0, selected.length - 2);
41383				}
41384			},
41385			/**
41386			 * Create a label.
41387			 *
41388			 * @param {jQuery} element
41389			 * @returns {String}
41390			 */
41391			optionLabel: function(element){
41392				return $(element).attr('label') || $(element).text();
41393			},
41394			/**
41395			 * Triggered on change of the multiselect.
41396			 *
41397			 * Not triggered when selecting/deselecting options manually.
41398			 *
41399			 * @param {jQuery} option
41400			 * @param {Boolean} checked
41401			 */
41402			onChange : function(option, checked) {
41403
41404			},
41405			/**
41406			 * Triggered when the dropdown is shown.
41407			 *
41408			 * @param {jQuery} event
41409			 */
41410			onDropdownShow: function(event) {
41411
41412			},
41413			/**
41414			 * Triggered when the dropdown is hidden.
41415			 *
41416			 * @param {jQuery} event
41417			 */
41418			onDropdownHide: function(event) {
41419
41420			},
41421			/**
41422			 * Triggered after the dropdown is shown.
41423			 *
41424			 * @param {jQuery} event
41425			 */
41426			onDropdownShown: function(event) {
41427
41428			},
41429			/**
41430			 * Triggered after the dropdown is hidden.
41431			 *
41432			 * @param {jQuery} event
41433			 */
41434			onDropdownHidden: function(event) {
41435
41436			},
41437			/**
41438			 * Triggered on select all.
41439			 */
41440			onSelectAll: function() {
41441
41442			},
41443			enableHTML: false,
41444			buttonClass: 'btn btn-default',
41445			inheritClass: false,
41446			buttonWidth: 'auto',
41447			buttonContainer: '<div class="btn-group" />',
41448			dropRight: false,
41449			selectedClass: 'active',
41450			// Maximum height of the dropdown menu.
41451			// If maximum height is exceeded a scrollbar will be displayed.
41452			maxHeight: false,
41453			checkboxName: false,
41454			includeSelectAllOption: false,
41455			includeSelectAllIfMoreThan: 0,
41456			selectAllText: ' Select all',
41457			selectAllValue: 'multiselect-all',
41458			selectAllName: false,
41459			selectAllNumber: true,
41460			enableFiltering: false,
41461			enableCaseInsensitiveFiltering: false,
41462			enableClickableOptGroups: false,
41463			filterPlaceholder: 'Search',
41464			// possible options: 'text', 'value', 'both'
41465			filterBehavior: 'text',
41466			includeFilterClearBtn: true,
41467			preventInputChangeEvent: false,
41468			nonSelectedText: 'None selected',
41469			nSelectedText: 'selected',
41470			allSelectedText: 'All selected',
41471			numberDisplayed: 3,
41472			disableIfEmpty: false,
41473			delimiterText: ', ',
41474			templates: {
41475				button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"><span class="multiselect-selected-text"></span> <b class="caret"></b></button>',
41476				ul: '<ul class="multiselect-container dropdown-menu"></ul>',
41477				filter: '<li class="multiselect-item filter"><div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span><input class="form-control multiselect-search" type="text"></div></li>',
41478				filterClearBtn: '<span class="input-group-btn"><button class="btn btn-default multiselect-clear-filter" type="button"><i class="glyphicon glyphicon-remove-circle"></i></button></span>',
41479				li: '<li><a tabindex="0"><label></label></a></li>',
41480				divider: '<li class="multiselect-item divider"></li>',
41481				liGroup: '<li class="multiselect-item multiselect-group"><label></label></li>'
41482			}
41483		},
41484
41485		constructor: Multiselect,
41486
41487		/**
41488		 * Builds the container of the multiselect.
41489		 */
41490		buildContainer: function() {
41491			this.$container = $(this.options.buttonContainer);
41492			this.$container.on('show.bs.dropdown', this.options.onDropdownShow);
41493			this.$container.on('hide.bs.dropdown', this.options.onDropdownHide);
41494			this.$container.on('shown.bs.dropdown', this.options.onDropdownShown);
41495			this.$container.on('hidden.bs.dropdown', this.options.onDropdownHidden);
41496		},
41497
41498		/**
41499		 * Builds the button of the multiselect.
41500		 */
41501		buildButton: function() {
41502			this.$button = $(this.options.templates.button).addClass(this.options.buttonClass);
41503			if (this.$select.attr('class') && this.options.inheritClass) {
41504				this.$button.addClass(this.$select.attr('class'));
41505			}
41506			// Adopt active state.
41507			if (this.$select.prop('disabled')) {
41508				this.disable();
41509			}
41510			else {
41511				this.enable();
41512			}
41513
41514			// Manually add button width if set.
41515			if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') {
41516				this.$button.css({
41517					'width' : this.options.buttonWidth,
41518					'overflow' : 'hidden',
41519					'text-overflow' : 'ellipsis'
41520				});
41521				this.$container.css({
41522					'width': this.options.buttonWidth
41523				});
41524			}
41525
41526			// Keep the tab index from the select.
41527			var tabindex = this.$select.attr('tabindex');
41528			if (tabindex) {
41529				this.$button.attr('tabindex', tabindex);
41530			}
41531
41532			this.$container.prepend(this.$button);
41533		},
41534
41535		/**
41536		 * Builds the ul representing the dropdown menu.
41537		 */
41538		buildDropdown: function() {
41539
41540			// Build ul.
41541			this.$ul = $(this.options.templates.ul);
41542
41543			if (this.options.dropRight) {
41544				this.$ul.addClass('pull-right');
41545			}
41546
41547			// Set max height of dropdown menu to activate auto scrollbar.
41548			if (this.options.maxHeight) {
41549				// TODO: Add a class for this option to move the css declarations.
41550				this.$ul.css({
41551					'max-height': this.options.maxHeight + 'px',
41552					'overflow-y': 'auto',
41553					'overflow-x': 'hidden'
41554				});
41555			}
41556
41557			this.$container.append(this.$ul);
41558		},
41559
41560		/**
41561		 * Build the dropdown options and binds all nessecary events.
41562		 *
41563		 * Uses createDivider and createOptionValue to create the necessary options.
41564		 */
41565		buildDropdownOptions: function() {
41566
41567			this.$select.children().each($.proxy(function(index, element) {
41568
41569				var $element = $(element);
41570				// Support optgroups and options without a group simultaneously.
41571				var tag = $element.prop('tagName')
41572					.toLowerCase();
41573
41574				if ($element.prop('value') === this.options.selectAllValue) {
41575					return;
41576				}
41577
41578				if (tag === 'optgroup') {
41579					this.createOptgroup(element);
41580				}
41581				else if (tag === 'option') {
41582
41583					if ($element.data('role') === 'divider') {
41584						this.createDivider();
41585					}
41586					else {
41587						this.createOptionValue(element);
41588					}
41589
41590				}
41591
41592				// Other illegal tags will be ignored.
41593			}, this));
41594
41595			// Bind the change event on the dropdown elements.
41596			$('li input', this.$ul).on('change', $.proxy(function(event) {
41597				var $target = $(event.target);
41598
41599				var checked = $target.prop('checked') || false;
41600				var isSelectAllOption = $target.val() === this.options.selectAllValue;
41601
41602				// Apply or unapply the configured selected class.
41603				if (this.options.selectedClass) {
41604					if (checked) {
41605						$target.closest('li')
41606							.addClass(this.options.selectedClass);
41607					}
41608					else {
41609						$target.closest('li')
41610							.removeClass(this.options.selectedClass);
41611					}
41612				}
41613
41614				// Get the corresponding option.
41615				var value = $target.val();
41616				var $option = this.getOptionByValue(value);
41617
41618				var $optionsNotThis = $('option', this.$select).not($option);
41619				var $checkboxesNotThis = $('input', this.$container).not($target);
41620
41621				if (isSelectAllOption) {
41622					if (checked) {
41623						this.selectAll();
41624					}
41625					else {
41626						this.deselectAll();
41627					}
41628				}
41629
41630				if(!isSelectAllOption){
41631					if (checked) {
41632						$option.prop('selected', true);
41633
41634						if (this.options.multiple) {
41635							// Simply select additional option.
41636							$option.prop('selected', true);
41637						}
41638						else {
41639							// Unselect all other options and corresponding checkboxes.
41640							if (this.options.selectedClass) {
41641								$($checkboxesNotThis).closest('li').removeClass(this.options.selectedClass);
41642							}
41643
41644							$($checkboxesNotThis).prop('checked', false);
41645							$optionsNotThis.prop('selected', false);
41646
41647							// It's a single selection, so close.
41648							this.$button.click();
41649						}
41650
41651						if (this.options.selectedClass === "active") {
41652							$optionsNotThis.closest("a").css("outline", "");
41653						}
41654					}
41655					else {
41656						// Unselect option.
41657						$option.prop('selected', false);
41658					}
41659				}
41660
41661				this.$select.change();
41662
41663				this.updateButtonText();
41664				this.updateSelectAll();
41665
41666				this.options.onChange($option, checked);
41667
41668				if(this.options.preventInputChangeEvent) {
41669					return false;
41670				}
41671			}, this));
41672
41673			$('li a', this.$ul).on('mousedown', function(e) {
41674				if (e.shiftKey) {
41675					// Prevent selecting text by Shift+click
41676					return false;
41677				}
41678			});
41679
41680			$('li a', this.$ul).on('touchstart click', $.proxy(function(event) {
41681				event.stopPropagation();
41682
41683				var $target = $(event.target);
41684
41685				if (event.shiftKey && this.options.multiple) {
41686					if($target.is("label")){ // Handles checkbox selection manually (see https://github.com/davidstutz/bootstrap-multiselect/issues/431)
41687						event.preventDefault();
41688						$target = $target.find("input");
41689						$target.prop("checked", !$target.prop("checked"));
41690					}
41691					var checked = $target.prop('checked') || false;
41692
41693					if (this.lastToggledInput !== null && this.lastToggledInput !== $target) { // Make sure we actually have a range
41694						var from = $target.closest("li").index();
41695						var to = this.lastToggledInput.closest("li").index();
41696
41697						if (from > to) { // Swap the indices
41698							var tmp = to;
41699							to = from;
41700							from = tmp;
41701						}
41702
41703						// Make sure we grab all elements since slice excludes the last index
41704						++to;
41705
41706						// Change the checkboxes and underlying options
41707						var range = this.$ul.find("li").slice(from, to).find("input");
41708
41709						range.prop('checked', checked);
41710
41711						if (this.options.selectedClass) {
41712							range.closest('li')
41713								.toggleClass(this.options.selectedClass, checked);
41714						}
41715
41716						for (var i = 0, j = range.length; i < j; i++) {
41717							var $checkbox = $(range[i]);
41718
41719							var $option = this.getOptionByValue($checkbox.val());
41720
41721							$option.prop('selected', checked);
41722						}
41723					}
41724
41725					// Trigger the select "change" event
41726					$target.trigger("change");
41727				}
41728
41729				// Remembers last clicked option
41730				if($target.is("input") && !$target.closest("li").is(".multiselect-item")){
41731					this.lastToggledInput = $target;
41732				}
41733
41734				$target.blur();
41735			}, this));
41736
41737			// Keyboard support.
41738			this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) {
41739				if ($('input[type="text"]', this.$container).is(':focus')) {
41740					return;
41741				}
41742
41743				if (event.keyCode === 9 && this.$container.hasClass('open')) {
41744					this.$button.click();
41745				}
41746				else {
41747					var $items = $(this.$container).find("li:not(.divider):not(.disabled) a").filter(":visible");
41748
41749					if (!$items.length) {
41750						return;
41751					}
41752
41753					var index = $items.index($items.filter(':focus'));
41754
41755					// Navigation up.
41756					if (event.keyCode === 38 && index > 0) {
41757						index--;
41758					}
41759					// Navigate down.
41760					else if (event.keyCode === 40 && index < $items.length - 1) {
41761						index++;
41762					}
41763					else if (!~index) {
41764						index = 0;
41765					}
41766
41767					var $current = $items.eq(index);
41768					$current.focus();
41769
41770					if (event.keyCode === 32 || event.keyCode === 13) {
41771						var $checkbox = $current.find('input');
41772
41773						$checkbox.prop("checked", !$checkbox.prop("checked"));
41774						$checkbox.change();
41775					}
41776
41777					event.stopPropagation();
41778					event.preventDefault();
41779				}
41780			}, this));
41781
41782			if(this.options.enableClickableOptGroups && this.options.multiple) {
41783				$('li.multiselect-group', this.$ul).on('click', $.proxy(function(event) {
41784					event.stopPropagation();
41785
41786					var group = $(event.target).parent();
41787
41788					// Search all option in optgroup
41789					var $options = group.nextUntil('li.multiselect-group');
41790					var $visibleOptions = $options.filter(":visible:not(.disabled)");
41791
41792					// check or uncheck items
41793					var allChecked = true;
41794					var optionInputs = $visibleOptions.find('input');
41795					optionInputs.each(function() {
41796						allChecked = allChecked && $(this).prop('checked');
41797					});
41798
41799					optionInputs.prop('checked', !allChecked).trigger('change');
41800				}, this));
41801			}
41802		},
41803
41804		/**
41805		 * Create an option using the given select option.
41806		 *
41807		 * @param {jQuery} element
41808		 */
41809		createOptionValue: function(element) {
41810			var $element = $(element);
41811			if ($element.is(':selected')) {
41812				$element.prop('selected', true);
41813			}
41814
41815			// Support the label attribute on options.
41816			var label = this.options.optionLabel(element);
41817			var value = $element.val();
41818			var inputType = this.options.multiple ? "checkbox" : "radio";
41819
41820			var $li = $(this.options.templates.li);
41821			var $label = $('label', $li);
41822			$label.addClass(inputType);
41823
41824			if (this.options.enableHTML) {
41825				$label.html(" " + label);
41826			}
41827			else {
41828				$label.text(" " + label);
41829			}
41830
41831			var $checkbox = $('<input/>').attr('type', inputType);
41832
41833			if (this.options.checkboxName) {
41834				$checkbox.attr('name', this.options.checkboxName);
41835			}
41836			$label.prepend($checkbox);
41837
41838			var selected = $element.prop('selected') || false;
41839			$checkbox.val(value);
41840
41841			if (value === this.options.selectAllValue) {
41842				$li.addClass("multiselect-item multiselect-all");
41843				$checkbox.parent().parent()
41844					.addClass('multiselect-all');
41845			}
41846
41847			$label.attr('title', $element.attr('title'));
41848
41849			this.$ul.append($li);
41850
41851			if ($element.is(':disabled')) {
41852				$checkbox.attr('disabled', 'disabled')
41853					.prop('disabled', true)
41854					.closest('a')
41855					.attr("tabindex", "-1")
41856					.closest('li')
41857					.addClass('disabled');
41858			}
41859
41860			$checkbox.prop('checked', selected);
41861
41862			if (selected && this.options.selectedClass) {
41863				$checkbox.closest('li')
41864					.addClass(this.options.selectedClass);
41865			}
41866		},
41867
41868		/**
41869		 * Creates a divider using the given select option.
41870		 *
41871		 * @param {jQuery} element
41872		 */
41873		createDivider: function(element) {
41874			var $divider = $(this.options.templates.divider);
41875			this.$ul.append($divider);
41876		},
41877
41878		/**
41879		 * Creates an optgroup.
41880		 *
41881		 * @param {jQuery} group
41882		 */
41883		createOptgroup: function(group) {
41884			var groupName = $(group).prop('label');
41885
41886			// Add a header for the group.
41887			var $li = $(this.options.templates.liGroup);
41888
41889			if (this.options.enableHTML) {
41890				$('label', $li).html(groupName);
41891			}
41892			else {
41893				$('label', $li).text(groupName);
41894			}
41895
41896			if (this.options.enableClickableOptGroups) {
41897				$li.addClass('multiselect-group-clickable');
41898			}
41899
41900			this.$ul.append($li);
41901
41902			if ($(group).is(':disabled')) {
41903				$li.addClass('disabled');
41904			}
41905
41906			// Add the options of the group.
41907			$('option', group).each($.proxy(function(index, element) {
41908				this.createOptionValue(element);
41909			}, this));
41910		},
41911
41912		/**
41913		 * Build the selct all.
41914		 *
41915		 * Checks if a select all has already been created.
41916		 */
41917		buildSelectAll: function() {
41918			if (typeof this.options.selectAllValue === 'number') {
41919				this.options.selectAllValue = this.options.selectAllValue.toString();
41920			}
41921
41922			var alreadyHasSelectAll = this.hasSelectAll();
41923
41924			if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple
41925				&& $('option', this.$select).length > this.options.includeSelectAllIfMoreThan) {
41926
41927				// Check whether to add a divider after the select all.
41928				if (this.options.includeSelectAllDivider) {
41929					this.$ul.prepend($(this.options.templates.divider));
41930				}
41931
41932				var $li = $(this.options.templates.li);
41933				$('label', $li).addClass("checkbox");
41934
41935				if (this.options.enableHTML) {
41936					$('label', $li).html(" " + this.options.selectAllText);
41937				}
41938				else {
41939					$('label', $li).text(" " + this.options.selectAllText);
41940				}
41941
41942				if (this.options.selectAllName) {
41943					$('label', $li).prepend('<input type="checkbox" name="' + this.options.selectAllName + '" />');
41944				}
41945				else {
41946					$('label', $li).prepend('<input type="checkbox" />');
41947				}
41948
41949				var $checkbox = $('input', $li);
41950				$checkbox.val(this.options.selectAllValue);
41951
41952				$li.addClass("multiselect-item multiselect-all");
41953				$checkbox.parent().parent()
41954					.addClass('multiselect-all');
41955
41956				this.$ul.prepend($li);
41957
41958				$checkbox.prop('checked', false);
41959			}
41960		},
41961
41962		/**
41963		 * Builds the filter.
41964		 */
41965		buildFilter: function() {
41966
41967			// Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength.
41968			if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) {
41969				var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering);
41970
41971				if (this.$select.find('option').length >= enableFilterLength) {
41972
41973					this.$filter = $(this.options.templates.filter);
41974					$('input', this.$filter).attr('placeholder', this.options.filterPlaceholder);
41975
41976					// Adds optional filter clear button
41977					if(this.options.includeFilterClearBtn){
41978						var clearBtn = $(this.options.templates.filterClearBtn);
41979						clearBtn.on('click', $.proxy(function(event){
41980							clearTimeout(this.searchTimeout);
41981							this.$filter.find('.multiselect-search').val('');
41982							$('li', this.$ul).show().removeClass("filter-hidden");
41983							this.updateSelectAll();
41984						}, this));
41985						this.$filter.find('.input-group').append(clearBtn);
41986					}
41987
41988					this.$ul.prepend(this.$filter);
41989
41990					this.$filter.val(this.query).on('click', function(event) {
41991						event.stopPropagation();
41992					}).on('input keydown', $.proxy(function(event) {
41993						// Cancel enter key default behaviour
41994						if (event.which === 13) {
41995							event.preventDefault();
41996						}
41997
41998						// This is useful to catch "keydown" events after the browser has updated the control.
41999						clearTimeout(this.searchTimeout);
42000
42001						this.searchTimeout = this.asyncFunction($.proxy(function() {
42002
42003							if (this.query !== event.target.value) {
42004								this.query = event.target.value;
42005
42006								var currentGroup, currentGroupVisible;
42007								$.each($('li', this.$ul), $.proxy(function(index, element) {
42008									var value = $('input', element).length > 0 ? $('input', element).val() : "";
42009									var text = $('label', element).text();
42010
42011									var filterCandidate = '';
42012									if ((this.options.filterBehavior === 'text')) {
42013										filterCandidate = text;
42014									}
42015									else if ((this.options.filterBehavior === 'value')) {
42016										filterCandidate = value;
42017									}
42018									else if (this.options.filterBehavior === 'both') {
42019										filterCandidate = text + '\n' + value;
42020									}
42021
42022									if (value !== this.options.selectAllValue && text) {
42023										// By default lets assume that element is not
42024										// interesting for this search.
42025										var showElement = false;
42026
42027										if (this.options.enableCaseInsensitiveFiltering && filterCandidate.toLowerCase().indexOf(this.query.toLowerCase()) > -1) {
42028											showElement = true;
42029										}
42030										else if (filterCandidate.indexOf(this.query) > -1) {
42031											showElement = true;
42032										}
42033
42034										// Toggle current element (group or group item) according to showElement boolean.
42035										$(element).toggle(showElement).toggleClass('filter-hidden', !showElement);
42036
42037										// Differentiate groups and group items.
42038										if ($(element).hasClass('multiselect-group')) {
42039											// Remember group status.
42040											currentGroup = element;
42041											currentGroupVisible = showElement;
42042										}
42043										else {
42044											// Show group name when at least one of its items is visible.
42045											if (showElement) {
42046												$(currentGroup).show().removeClass('filter-hidden');
42047											}
42048
42049											// Show all group items when group name satisfies filter.
42050											if (!showElement && currentGroupVisible) {
42051												$(element).show().removeClass('filter-hidden');
42052											}
42053										}
42054									}
42055								}, this));
42056							}
42057
42058							this.updateSelectAll();
42059						}, this), 300, this);
42060					}, this));
42061				}
42062			}
42063		},
42064
42065		/**
42066		 * Unbinds the whole plugin.
42067		 */
42068		destroy: function() {
42069			this.$container.remove();
42070			this.$select.show();
42071			this.$select.data('multiselect', null);
42072		},
42073
42074		/**
42075		 * Refreshs the multiselect based on the selected options of the select.
42076		 */
42077		refresh: function() {
42078			$('option', this.$select).each($.proxy(function(index, element) {
42079				var $input = $('li input', this.$ul).filter(function() {
42080					return $(this).val() === $(element).val();
42081				});
42082
42083				if ($(element).is(':selected')) {
42084					$input.prop('checked', true);
42085
42086					if (this.options.selectedClass) {
42087						$input.closest('li')
42088							.addClass(this.options.selectedClass);
42089					}
42090				}
42091				else {
42092					$input.prop('checked', false);
42093
42094					if (this.options.selectedClass) {
42095						$input.closest('li')
42096							.removeClass(this.options.selectedClass);
42097					}
42098				}
42099
42100				if ($(element).is(":disabled")) {
42101					$input.attr('disabled', 'disabled')
42102						.prop('disabled', true)
42103						.closest('li')
42104						.addClass('disabled');
42105				}
42106				else {
42107					$input.prop('disabled', false)
42108						.closest('li')
42109						.removeClass('disabled');
42110				}
42111			}, this));
42112
42113			this.updateButtonText();
42114			this.updateSelectAll();
42115		},
42116
42117		/**
42118		 * Select all options of the given values.
42119		 *
42120		 * If triggerOnChange is set to true, the on change event is triggered if
42121		 * and only if one value is passed.
42122		 *
42123		 * @param {Array} selectValues
42124		 * @param {Boolean} triggerOnChange
42125		 */
42126		select: function(selectValues, triggerOnChange) {
42127			if(!$.isArray(selectValues)) {
42128				selectValues = [selectValues];
42129			}
42130
42131			for (var i = 0; i < selectValues.length; i++) {
42132				var value = selectValues[i];
42133
42134				if (value === null || value === undefined) {
42135					continue;
42136				}
42137
42138				var $option = this.getOptionByValue(value);
42139				var $checkbox = this.getInputByValue(value);
42140
42141				if($option === undefined || $checkbox === undefined) {
42142					continue;
42143				}
42144
42145				if (!this.options.multiple) {
42146					this.deselectAll(false);
42147				}
42148
42149				if (this.options.selectedClass) {
42150					$checkbox.closest('li')
42151						.addClass(this.options.selectedClass);
42152				}
42153
42154				$checkbox.prop('checked', true);
42155				$option.prop('selected', true);
42156
42157				if (triggerOnChange) {
42158					this.options.onChange($option, true);
42159				}
42160			}
42161
42162			this.updateButtonText();
42163			this.updateSelectAll();
42164		},
42165
42166		/**
42167		 * Clears all selected items.
42168		 */
42169		clearSelection: function () {
42170			this.deselectAll(false);
42171			this.updateButtonText();
42172			this.updateSelectAll();
42173		},
42174
42175		/**
42176		 * Deselects all options of the given values.
42177		 *
42178		 * If triggerOnChange is set to true, the on change event is triggered, if
42179		 * and only if one value is passed.
42180		 *
42181		 * @param {Array} deselectValues
42182		 * @param {Boolean} triggerOnChange
42183		 */
42184		deselect: function(deselectValues, triggerOnChange) {
42185			if(!$.isArray(deselectValues)) {
42186				deselectValues = [deselectValues];
42187			}
42188
42189			for (var i = 0; i < deselectValues.length; i++) {
42190				var value = deselectValues[i];
42191
42192				if (value === null || value === undefined) {
42193					continue;
42194				}
42195
42196				var $option = this.getOptionByValue(value);
42197				var $checkbox = this.getInputByValue(value);
42198
42199				if($option === undefined || $checkbox === undefined) {
42200					continue;
42201				}
42202
42203				if (this.options.selectedClass) {
42204					$checkbox.closest('li')
42205						.removeClass(this.options.selectedClass);
42206				}
42207
42208				$checkbox.prop('checked', false);
42209				$option.prop('selected', false);
42210
42211				if (triggerOnChange) {
42212					this.options.onChange($option, false);
42213				}
42214			}
42215
42216			this.updateButtonText();
42217			this.updateSelectAll();
42218		},
42219
42220		/**
42221		 * Selects all enabled & visible options.
42222		 *
42223		 * If justVisible is true or not specified, only visible options are selected.
42224		 *
42225		 * @param {Boolean} justVisible
42226		 * @param {Boolean} triggerOnSelectAll
42227		 */
42228		selectAll: function (justVisible, triggerOnSelectAll) {
42229			var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
42230			var allCheckboxes = $("li input[type='checkbox']:enabled", this.$ul);
42231			var visibleCheckboxes = allCheckboxes.filter(":visible");
42232			var allCheckboxesCount = allCheckboxes.length;
42233			var visibleCheckboxesCount = visibleCheckboxes.length;
42234
42235			if(justVisible) {
42236				visibleCheckboxes.prop('checked', true);
42237				$("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").addClass(this.options.selectedClass);
42238			}
42239			else {
42240				allCheckboxes.prop('checked', true);
42241				$("li:not(.divider):not(.disabled)", this.$ul).addClass(this.options.selectedClass);
42242			}
42243
42244			if (allCheckboxesCount === visibleCheckboxesCount || justVisible === false) {
42245				$("option:enabled", this.$select).prop('selected', true);
42246			}
42247			else {
42248				var values = visibleCheckboxes.map(function() {
42249					return $(this).val();
42250				}).get();
42251
42252				$("option:enabled", this.$select).filter(function(index) {
42253					return $.inArray($(this).val(), values) !== -1;
42254				}).prop('selected', true);
42255			}
42256
42257			if (triggerOnSelectAll) {
42258				this.options.onSelectAll();
42259			}
42260		},
42261
42262		/**
42263		 * Deselects all options.
42264		 *
42265		 * If justVisible is true or not specified, only visible options are deselected.
42266		 *
42267		 * @param {Boolean} justVisible
42268		 */
42269		deselectAll: function (justVisible) {
42270			var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
42271
42272			if(justVisible) {
42273				var visibleCheckboxes = $("li input[type='checkbox']:not(:disabled)", this.$ul).filter(":visible");
42274				visibleCheckboxes.prop('checked', false);
42275
42276				var values = visibleCheckboxes.map(function() {
42277					return $(this).val();
42278				}).get();
42279
42280				$("option:enabled", this.$select).filter(function(index) {
42281					return $.inArray($(this).val(), values) !== -1;
42282				}).prop('selected', false);
42283
42284				if (this.options.selectedClass) {
42285					$("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").removeClass(this.options.selectedClass);
42286				}
42287			}
42288			else {
42289				$("li input[type='checkbox']:enabled", this.$ul).prop('checked', false);
42290				$("option:enabled", this.$select).prop('selected', false);
42291
42292				if (this.options.selectedClass) {
42293					$("li:not(.divider):not(.disabled)", this.$ul).removeClass(this.options.selectedClass);
42294				}
42295			}
42296		},
42297
42298		/**
42299		 * Rebuild the plugin.
42300		 *
42301		 * Rebuilds the dropdown, the filter and the select all option.
42302		 */
42303		rebuild: function() {
42304			this.$ul.html('');
42305
42306			// Important to distinguish between radios and checkboxes.
42307			this.options.multiple = this.$select.attr('multiple') === "multiple";
42308
42309			this.buildSelectAll();
42310			this.buildDropdownOptions();
42311			this.buildFilter();
42312
42313			this.updateButtonText();
42314			this.updateSelectAll();
42315
42316			if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) {
42317				this.disable();
42318			}
42319			else {
42320				this.enable();
42321			}
42322
42323			if (this.options.dropRight) {
42324				this.$ul.addClass('pull-right');
42325			}
42326		},
42327
42328		/**
42329		 * The provided data will be used to build the dropdown.
42330		 */
42331		dataprovider: function(dataprovider) {
42332
42333			var groupCounter = 0;
42334			var $select = this.$select.empty();
42335
42336			$.each(dataprovider, function (index, option) {
42337				var $tag;
42338
42339				if ($.isArray(option.children)) { // create optiongroup tag
42340					groupCounter++;
42341
42342					$tag = $('<optgroup/>').attr({
42343						label: option.label || 'Group ' + groupCounter,
42344						disabled: !!option.disabled
42345					});
42346
42347					forEach(option.children, function(subOption) { // add children option tags
42348						$tag.append($('<option/>').attr({
42349							value: subOption.value,
42350							label: subOption.label || subOption.value,
42351							title: subOption.title,
42352							selected: !!subOption.selected,
42353							disabled: !!subOption.disabled
42354						}));
42355					});
42356				}
42357				else {
42358					$tag = $('<option/>').attr({
42359						value: option.value,
42360						label: option.label || option.value,
42361						title: option.title,
42362						selected: !!option.selected,
42363						disabled: !!option.disabled
42364					});
42365				}
42366
42367				$select.append($tag);
42368			});
42369
42370			this.rebuild();
42371		},
42372
42373		/**
42374		 * Enable the multiselect.
42375		 */
42376		enable: function() {
42377			this.$select.prop('disabled', false);
42378			this.$button.prop('disabled', false)
42379				.removeClass('disabled');
42380		},
42381
42382		/**
42383		 * Disable the multiselect.
42384		 */
42385		disable: function() {
42386			this.$select.prop('disabled', true);
42387			this.$button.prop('disabled', true)
42388				.addClass('disabled');
42389		},
42390
42391		/**
42392		 * Set the options.
42393		 *
42394		 * @param {Array} options
42395		 */
42396		setOptions: function(options) {
42397			this.options = this.mergeOptions(options);
42398		},
42399
42400		/**
42401		 * Merges the given options with the default options.
42402		 *
42403		 * @param {Array} options
42404		 * @returns {Array}
42405		 */
42406		mergeOptions: function(options) {
42407			return $.extend(true, {}, this.defaults, this.options, options);
42408		},
42409
42410		/**
42411		 * Checks whether a select all checkbox is present.
42412		 *
42413		 * @returns {Boolean}
42414		 */
42415		hasSelectAll: function() {
42416			return $('li.multiselect-all', this.$ul).length > 0;
42417		},
42418
42419		/**
42420		 * Updates the select all checkbox based on the currently displayed and selected checkboxes.
42421		 */
42422		updateSelectAll: function() {
42423			if (this.hasSelectAll()) {
42424				var allBoxes = $("li:not(.multiselect-item):not(.filter-hidden) input:enabled", this.$ul);
42425				var allBoxesLength = allBoxes.length;
42426				var checkedBoxesLength = allBoxes.filter(":checked").length;
42427				var selectAllLi  = $("li.multiselect-all", this.$ul);
42428				var selectAllInput = selectAllLi.find("input");
42429
42430				if (checkedBoxesLength > 0 && checkedBoxesLength === allBoxesLength) {
42431					selectAllInput.prop("checked", true);
42432					selectAllLi.addClass(this.options.selectedClass);
42433					this.options.onSelectAll();
42434				}
42435				else {
42436					selectAllInput.prop("checked", false);
42437					selectAllLi.removeClass(this.options.selectedClass);
42438				}
42439			}
42440		},
42441
42442		/**
42443		 * Update the button text and its title based on the currently selected options.
42444		 */
42445		updateButtonText: function() {
42446			var options = this.getSelected();
42447
42448			// First update the displayed button text.
42449			if (this.options.enableHTML) {
42450				$('.multiselect .multiselect-selected-text', this.$container).html(this.options.buttonText(options, this.$select));
42451			}
42452			else {
42453				$('.multiselect .multiselect-selected-text', this.$container).text(this.options.buttonText(options, this.$select));
42454			}
42455
42456			// Now update the title attribute of the button.
42457			$('.multiselect', this.$container).attr('title', this.options.buttonTitle(options, this.$select));
42458		},
42459
42460		/**
42461		 * Get all selected options.
42462		 *
42463		 * @returns {jQUery}
42464		 */
42465		getSelected: function() {
42466			return $('option', this.$select).filter(":selected");
42467		},
42468
42469		/**
42470		 * Gets a select option by its value.
42471		 *
42472		 * @param {String} value
42473		 * @returns {jQuery}
42474		 */
42475		getOptionByValue: function (value) {
42476
42477			var options = $('option', this.$select);
42478			var valueToCompare = value.toString();
42479
42480			for (var i = 0; i < options.length; i = i + 1) {
42481				var option = options[i];
42482				if (option.value === valueToCompare) {
42483					return $(option);
42484				}
42485			}
42486		},
42487
42488		/**
42489		 * Get the input (radio/checkbox) by its value.
42490		 *
42491		 * @param {String} value
42492		 * @returns {jQuery}
42493		 */
42494		getInputByValue: function (value) {
42495
42496			var checkboxes = $('li input', this.$ul);
42497			var valueToCompare = value.toString();
42498
42499			for (var i = 0; i < checkboxes.length; i = i + 1) {
42500				var checkbox = checkboxes[i];
42501				if (checkbox.value === valueToCompare) {
42502					return $(checkbox);
42503				}
42504			}
42505		},
42506
42507		/**
42508		 * Used for knockout integration.
42509		 */
42510		updateOriginalOptions: function() {
42511			this.originalOptions = this.$select.clone()[0].options;
42512		},
42513
42514		asyncFunction: function(callback, timeout, self) {
42515			var args = Array.prototype.slice.call(arguments, 3);
42516			return setTimeout(function() {
42517				callback.apply(self || window, args);
42518			}, timeout);
42519		},
42520
42521		setAllSelectedText: function(allSelectedText) {
42522			this.options.allSelectedText = allSelectedText;
42523			this.updateButtonText();
42524		}
42525	};
42526
42527	$.fn.multiselect = function(option, parameter, extraOptions) {
42528		return this.each(function() {
42529			var data = $(this).data('multiselect');
42530			var options = typeof option === 'object' && option;
42531
42532			// Initialize the multiselect.
42533			if (!data) {
42534				data = new Multiselect(this, options);
42535				$(this).data('multiselect', data);
42536			}
42537
42538			// Call multiselect method.
42539			if (typeof option === 'string') {
42540				data[option](parameter, extraOptions);
42541
42542				if (option === 'destroy') {
42543					$(this).data('multiselect', false);
42544				}
42545			}
42546		});
42547	};
42548
42549	$.fn.multiselect.Constructor = Multiselect;
42550
42551	$(function() {
42552		$("select[data-role=multiselect]").multiselect();
42553	});
42554
42555}(window.jQuery);
42556
42557/*
42558 * International Telephone Input v12.0.2
42559 * https://github.com/jackocnr/intl-tel-input.git
42560 * Licensed under the MIT license
42561 */
42562// wrap in UMD - see https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
42563(function(factory) {
42564	if (typeof define === "function" && define.amd) {
42565		define([ "jquery" ], function($) {
42566			factory($, window, document);
42567		});
42568	} else if (typeof module === "object" && module.exports) {
42569		module.exports = factory(require("jquery"), window, document);
42570	} else {
42571		factory(jQuery, window, document);
42572	}
42573})(function($, window, document, undefined) {
42574	"use strict";
42575	// these vars persist through all instances of the plugin
42576	var pluginName = "intlTelInput", id = 1, // give each instance it's own id for namespaced event handling
42577		defaults = {
42578			// whether or not to allow the dropdown
42579			allowDropdown: true,
42580			// if there is just a dial code in the input: remove it on blur, and re-add it on focus
42581			autoHideDialCode: true,
42582			// add a placeholder in the input with an example number for the selected country
42583			autoPlaceholder: "polite",
42584			// modify the auto placeholder
42585			customPlaceholder: null,
42586			// append menu to a specific element
42587			dropdownContainer: "",
42588			// don't display these countries
42589			excludeCountries: [],
42590			// format the input value during initialisation and on setNumber
42591			formatOnDisplay: true,
42592			// geoIp lookup function
42593			geoIpLookup: null,
42594			// inject a hidden input with this name, and on submit, populate it with the result of getNumber
42595			hiddenInput: "",
42596			// initial country
42597			initialCountry: "",
42598			// don't insert international dial codes
42599			nationalMode: true,
42600			// display only these countries
42601			onlyCountries: [],
42602			// number type to use for placeholders
42603			placeholderNumberType: "MOBILE",
42604			// the countries at the top of the list. defaults to united states and united kingdom
42605			preferredCountries: [ "us", "gb" ],
42606			// display the country dial code next to the selected flag so it's not part of the typed number
42607			separateDialCode: false,
42608			// specify the path to the libphonenumber script to enable validation/formatting
42609			utilsScript: ""
42610		}, keys = {
42611			UP: 38,
42612			DOWN: 40,
42613			ENTER: 13,
42614			ESC: 27,
42615			PLUS: 43,
42616			A: 65,
42617			Z: 90,
42618			SPACE: 32,
42619			TAB: 9
42620		}, // https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes#Non-geographic_area_codes
42621		regionlessNanpNumbers = [ "800", "822", "833", "844", "855", "866", "877", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889" ];
42622	// keep track of if the window.load event has fired as impossible to check after the fact
42623	$(window).on("load", function() {
42624		// UPDATE: use a public static field so we can fudge it in the tests
42625		$.fn[pluginName].windowLoaded = true;
42626	});
42627	function Plugin(element, options) {
42628		this.telInput = $(element);
42629		this.options = $.extend({}, defaults, options);
42630		// event namespace
42631		this.ns = "." + pluginName + id++;
42632		// Chrome, FF, Safari, IE9+
42633		this.isGoodBrowser = Boolean(element.setSelectionRange);
42634		this.hadInitialPlaceholder = Boolean($(element).attr("placeholder"));
42635	}
42636	Plugin.prototype = {
42637		_init: function() {
42638			// if in nationalMode, disable options relating to dial codes
42639			if (this.options.nationalMode) {
42640				this.options.autoHideDialCode = false;
42641			}
42642			// if separateDialCode then doesn't make sense to A) insert dial code into input (autoHideDialCode), and B) display national numbers (because we're displaying the country dial code next to them)
42643			if (this.options.separateDialCode) {
42644				this.options.autoHideDialCode = this.options.nationalMode = false;
42645			}
42646			// we cannot just test screen size as some smartphones/website meta tags will report desktop resolutions
42647			// Note: for some reason jasmine breaks if you put this in the main Plugin function with the rest of these declarations
42648			// Note: to target Android Mobiles (and not Tablets), we must find "Android" and "Mobile"
42649			this.isMobile = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
42650			if (this.isMobile) {
42651				// trigger the mobile dropdown css
42652				$("body").addClass("iti-mobile");
42653				// on mobile, we want a full screen dropdown, so we must append it to the body
42654				if (!this.options.dropdownContainer) {
42655					this.options.dropdownContainer = "body";
42656				}
42657			}
42658			// we return these deferred objects from the _init() call so they can be watched, and then we resolve them when each specific request returns
42659			// Note: again, jasmine breaks when I put these in the Plugin function
42660			this.autoCountryDeferred = new $.Deferred();
42661			this.utilsScriptDeferred = new $.Deferred();
42662			// in various situations there could be no country selected initially, but we need to be able to assume this variable exists
42663			this.selectedCountryData = {};
42664			// process all the data: onlyCountries, excludeCountries, preferredCountries etc
42665			this._processCountryData();
42666			// generate the markup
42667			this._generateMarkup();
42668			// set the initial state of the input value and the selected flag
42669			this._setInitialState();
42670			// start all of the event listeners: autoHideDialCode, input keydown, selectedFlag click
42671			this._initListeners();
42672			// utils script, and auto country
42673			this._initRequests();
42674			// return the deferreds
42675			return [ this.autoCountryDeferred, this.utilsScriptDeferred ];
42676		},
42677		/********************
42678		 *  PRIVATE METHODS
42679		 ********************/
42680		// prepare all of the country data, including onlyCountries, excludeCountries and preferredCountries options
42681		_processCountryData: function() {
42682			// process onlyCountries or excludeCountries array if present
42683			this._processAllCountries();
42684			// process the countryCodes map
42685			this._processCountryCodes();
42686			// process the preferredCountries
42687			this._processPreferredCountries();
42688		},
42689		// add a country code to this.countryCodes
42690		_addCountryCode: function(iso2, dialCode, priority) {
42691			if (!(dialCode in this.countryCodes)) {
42692				this.countryCodes[dialCode] = [];
42693			}
42694			var index = priority || 0;
42695			this.countryCodes[dialCode][index] = iso2;
42696		},
42697		// process onlyCountries or excludeCountries array if present
42698		_processAllCountries: function() {
42699			if (this.options.onlyCountries.length) {
42700				var lowerCaseOnlyCountries = this.options.onlyCountries.map(function(country) {
42701					return country.toLowerCase();
42702				});
42703				this.countries = allCountries.filter(function(country) {
42704					return lowerCaseOnlyCountries.indexOf(country.iso2) > -1;
42705				});
42706			} else if (this.options.excludeCountries.length) {
42707				var lowerCaseExcludeCountries = this.options.excludeCountries.map(function(country) {
42708					return country.toLowerCase();
42709				});
42710				this.countries = allCountries.filter(function(country) {
42711					return lowerCaseExcludeCountries.indexOf(country.iso2) === -1;
42712				});
42713			} else {
42714				this.countries = allCountries;
42715			}
42716		},
42717		// process the countryCodes map
42718		_processCountryCodes: function() {
42719			this.countryCodes = {};
42720			for (var i = 0; i < this.countries.length; i++) {
42721				var c = this.countries[i];
42722				this._addCountryCode(c.iso2, c.dialCode, c.priority);
42723				// area codes
42724				if (c.areaCodes) {
42725					for (var j = 0; j < c.areaCodes.length; j++) {
42726						// full dial code is country code + dial code
42727						this._addCountryCode(c.iso2, c.dialCode + c.areaCodes[j]);
42728					}
42729				}
42730			}
42731		},
42732		// process preferred countries - iterate through the preferences, fetching the country data for each one
42733		_processPreferredCountries: function() {
42734			this.preferredCountries = [];
42735			for (var i = 0; i < this.options.preferredCountries.length; i++) {
42736				var countryCode = this.options.preferredCountries[i].toLowerCase(), countryData = this._getCountryData(countryCode, false, true);
42737				if (countryData) {
42738					this.preferredCountries.push(countryData);
42739				}
42740			}
42741		},
42742		// generate all of the markup for the plugin: the selected flag overlay, and the dropdown
42743		_generateMarkup: function() {
42744			// prevent autocomplete as there's no safe, cross-browser event we can react to, so it can easily put the plugin in an inconsistent state e.g. the wrong flag selected for the autocompleted number, which on submit c
42744ould mean the wrong number is saved (esp in nationalMode)
42745			this.telInput.attr("autocomplete", "off");
42746			// containers (mostly for positioning)
42747			var parentClass = "intl-tel-input";
42748			if (this.options.allowDropdown) {
42749				parentClass += " allow-dropdown";
42750			}
42751			if (this.options.separateDialCode) {
42752				parentClass += " separate-dial-code";
42753			}
42754			this.telInput.wrap($("<div>", {
42755				"class": parentClass
42756			}));
42757			this.flagsContainer = $("<div>", {
42758				"class": "flag-container"
42759			}).insertBefore(this.telInput);
42760			// currently selected flag (displayed to left of input)
42761			var selectedFlag = $("<div>", {
42762				"class": "selected-flag"
42763			});
42764			selectedFlag.appendTo(this.flagsContainer);
42765			this.selectedFlagInner = $("<div>", {
42766				"class": "iti-flag"
42767			}).appendTo(selectedFlag);
42768			if (this.options.separateDialCode) {
42769				this.selectedDialCode = $("<div>", {
42770					"class": "selected-dial-code"
42771				}).appendTo(selectedFlag);
42772			}
42773			if (this.options.allowDropdown) {
42774				// make element focusable and tab naviagable
42775				selectedFlag.attr("tabindex", "0");
42776				// CSS triangle
42777				$("<div>", {
42778					"class": "iti-arrow"
42779				}).appendTo(selectedFlag);
42780				// country dropdown: preferred countries, then divider, then all countries
42781				this.countryList = $("<ul>", {
42782					"class": "country-list hide"
42783				});
42784				if (this.preferredCountries.length) {
42785					this._appendListItems(this.preferredCountries, "preferred");
42786					$("<li>", {
42787						"class": "divider"
42788					}).appendTo(this.countryList);
42789				}
42790				this._appendListItems(this.countries, "");
42791				// this is useful in lots of places
42792				this.countryListItems = this.countryList.children(".country");
42793				// create dropdownContainer markup
42794				if (this.options.dropdownContainer) {
42795					this.dropdown = $("<div>", {
42796						"class": "intl-tel-input iti-container"
42797					}).append(this.countryList);
42798				} else {
42799					this.countryList.appendTo(this.flagsContainer);
42800				}
42801			} else {
42802				// a little hack so we don't break anything
42803				this.countryListItems = $();
42804			}
42805			if (this.options.hiddenInput) {
42806				this.hiddenInput = $("<input>", {
42807					type: "hidden",
42808					name: this.options.hiddenInput
42809				}).insertBefore(this.telInput);
42810			}
42811		},
42812		// add a country <li> to the countryList <ul> container
42813		_appendListItems: function(countries, className) {
42814			// we create so many DOM elements, it is faster to build a temp string
42815			// and then add everything to the DOM in one go at the end
42816			var tmp = "";
42817			// for each country
42818			for (var i = 0; i < countries.length; i++) {
42819				var c = countries[i];
42820				// open the list item
42821				tmp += "<li class='country " + className + "' data-dial-code='" + c.dialCode + "' data-country-code='" + c.iso2 + "'>";
42822				// add the flag
42823				tmp += "<div class='flag-box'><div class='iti-flag " + c.iso2 + "'></div></div>";
42824				// and the country name and dial code
42825				tmp += "<span class='country-name'>" + c.name + "</span>";
42826				tmp += "<span class='dial-code'>+" + c.dialCode + "</span>";
42827				// close the list item
42828				tmp += "</li>";
42829			}
42830			this.countryList.append(tmp);
42831		},
42832		// set the initial state of the input value and the selected flag by:
42833		// 1. extracting a dial code from the given number
42834		// 2. using explicit initialCountry
42835		// 3. picking the first preferred country
42836		// 4. picking the first country
42837		_setInitialState: function() {
42838			var val = this.telInput.val();
42839			// if we already have a dial code, and it's not a regionlessNanp, we can go ahead and set the flag, else fall back to the default country
42840			// UPDATE: actually we do want to set the flag for a regionlessNanp in one situation: if we're in nationalMode and there's no initialCountry - otherwise we lose the +1 and we're left with an invalid number
42841			if (this._getDialCode(val) && (!this._isRegionlessNanp(val) || this.options.nationalMode && !this.options.initialCountry)) {
42842				this._updateFlagFromNumber(val);
42843			} else if (this.options.initialCountry !== "auto") {
42844				// see if we should select a flag
42845				if (this.options.initialCountry) {
42846					this._setFlag(this.options.initialCountry.toLowerCase());
42847				} else {
42848					// no dial code and no initialCountry, so default to first in list
42849					this.defaultCountry = this.preferredCountries.length ? this.preferredCountries[0].iso2 : this.countries[0].iso2;
42850					if (!val) {
42851						this._setFlag(this.defaultCountry);
42852					}
42853				}
42854				// if empty and no nationalMode and no autoHideDialCode then insert the default dial code
42855				if (!val && !this.options.nationalMode && !this.options.autoHideDialCode && !this.options.separateDialCode) {
42856					this.telInput.val("+" + this.selectedCountryData.dialCode);
42857				}
42858			}
42859			// NOTE: if initialCountry is set to auto, that will be handled separately
42860			// format
42861			if (val) {
42862				// this wont be run after _updateDialCode as that's only called if no val
42863				this._updateValFromNumber(val);
42864			}
42865		},
42866		// initialise the main event listeners: input keyup, and click selected flag
42867		_initListeners: function() {
42868			this._initKeyListeners();
42869			if (this.options.autoHideDialCode) {
42870				this._initFocusListeners();
42871			}
42872			if (this.options.allowDropdown) {
42873				this._initDropdownListeners();
42874			}
42875			if (this.hiddenInput) {
42876				this._initHiddenInputListener();
42877			}
42878		},
42879		// update hidden input on form submit
42880		_initHiddenInputListener: function() {
42881			var that = this;
42882			var form = this.telInput.closest("form");
42883			if (form.length) {
42884				form.submit(function() {
42885					that.hiddenInput.val(that.getNumber());
42886				});
42887			}
42888		},
42889		// initialise the dropdown listeners
42890		_initDropdownListeners: function() {
42891			var that = this;
42892			// hack for input nested inside label: clicking the selected-flag to open the dropdown would then automatically trigger a 2nd click on the input which would close it again
42893			var label = this.telInput.closest("label");
42894			if (label.length) {
42895				label.on("click" + this.ns, function(e) {
42896					// if the dropdown is closed, then focus the input, else ignore the click
42897					if (that.countryList.hasClass("hide")) {
42898						that.telInput.focus();
42899					} else {
42900						e.preventDefault();
42901					}
42902				});
42903			}
42904			// toggle country dropdown on click
42905			var selectedFlag = this.selectedFlagInner.parent();
42906			selectedFlag.on("click" + this.ns, function(e) {
42907				// only intercept this event if we're opening the dropdown
42908				// else let it bubble up to the top ("click-off-to-close" listener)
42909				// we cannot just stopPropagation as it may be needed to close another instance
42910				if (that.countryList.hasClass("hide") && !that.telInput.prop("disabled") && !that.telInput.prop("readonly")) {
42911					that._showDropdown();
42912				}
42913			});
42914			// open dropdown list if currently focused
42915			this.flagsContainer.on("keydown" + that.ns, function(e) {
42916				var isDropdownHidden = that.countryList.hasClass("hide");
42917				if (isDropdownHidden && (e.which == keys.UP || e.which == keys.DOWN || e.which == keys.SPACE || e.which == keys.ENTER)) {
42918					// prevent form from being submitted if "ENTER" was pressed
42919					e.preventDefault();
42920					// prevent event from being handled again by document
42921					e.stopPropagation();
42922					that._showDropdown();
42923				}
42924				// allow navigation from dropdown to input on TAB
42925				if (e.which == keys.TAB) {
42926					that._closeDropdown();
42927				}
42928			});
42929		},
42930		// init many requests: utils script / geo ip lookup
42931		_initRequests: function() {
42932			var that = this;
42933			// if the user has specified the path to the utils script, fetch it on window.load, else resolve
42934			if (this.options.utilsScript) {
42935				// if the plugin is being initialised after the window.load event has already been fired
42936				if ($.fn[pluginName].windowLoaded) {
42937					$.fn[pluginName].loadUtils(this.options.utilsScript, this.utilsScriptDeferred);
42938				} else {
42939					// wait until the load event so we don't block any other requests e.g. the flags image
42940					$(window).on("load", function() {
42941						$.fn[pluginName].loadUtils(that.options.utilsScript, that.utilsScriptDeferred);
42942					});
42943				}
42944			} else {
42945				this.utilsScriptDeferred.resolve();
42946			}
42947			if (this.options.initialCountry === "auto") {
42948				this._loadAutoCountry();
42949			} else {
42950				this.autoCountryDeferred.resolve();
42951			}
42952		},
42953		// perform the geo ip lookup
42954		_loadAutoCountry: function() {
42955			var that = this;
42956			// 3 options:
42957			// 1) already loaded (we're done)
42958			// 2) not already started loading (start)
42959			// 3) already started loading (do nothing - just wait for loading callback to fire)
42960			if ($.fn[pluginName].autoCountry) {
42961				this.handleAutoCountry();
42962			} else if (!$.fn[pluginName].startedLoadingAutoCountry) {
42963				// don't do this twice!
42964				$.fn[pluginName].startedLoadingAutoCountry = true;
42965				if (typeof this.options.geoIpLookup === "function") {
42966					this.options.geoIpLookup(function(countryCode) {
42967						$.fn[pluginName].autoCountry = countryCode.toLowerCase();
42968						// tell all instances the auto country is ready
42969						// TODO: this should just be the current instances
42970						// UPDATE: use setTimeout in case their geoIpLookup function calls this callback straight away (e.g. if they have already done the geo ip lookup somewhere else). Using setTimeout means that the current thread of execution will finish before executing this, which allows the plugin to finish initialising.
42971						setTimeout(function() {
42972							$(".intl-tel-input input").intlTelInput("handleAutoCountry");
42973						});
42974					});
42975				}
42976			}
42977		},
42978		// initialize any key listeners
42979		_initKeyListeners: function() {
42980			var that = this;
42981			// update flag on keyup
42982			// (keep this listener separate otherwise the setTimeout breaks all the tests)
42983			this.telInput.on("keyup" + this.ns, function() {
42984				if (that._updateFlagFromNumber(that.telInput.val())) {
42985					that._triggerCountryChange();
42986				}
42987			});
42988			// update flag on cut/paste events (now supported in all major browsers)
42989			this.telInput.on("cut" + this.ns + " paste" + this.ns, function() {
42990				// hack because "paste" event is fired before input is updated
42991				setTimeout(function() {
42992					if (that._updateFlagFromNumber(that.telInput.val())) {
42993						that._triggerCountryChange();
42994					}
42995				});
42996			});
42997		},
42998		// adhere to the input's maxlength attr
42999		_cap: function(number) {
43000			var max = this.telInput.attr("maxlength");
43001			return max && number.length > max ? number.substr(0, max) : number;
43002		},
43003		// listen for mousedown, focus and blur
43004		_initFocusListeners: function() {
43005			var that = this;
43006			// mousedown decides where the cursor goes, so if we're focusing we must preventDefault as we'll be inserting the dial code, and we want the cursor to be at the end no matter where they click
43007			this.telInput.on("mousedown" + this.ns, function(e) {
43008				if (!that.telInput.is(":focus") && !that.telInput.val()) {
43009					e.preventDefault();
43010					// but this also cancels the focus, so we must trigger that manually
43011					that.telInput.focus();
43012				}
43013			});
43014			// on focus: if empty, insert the dial code for the currently selected flag
43015			this.telInput.on("focus" + this.ns, function(e) {
43016				if (!that.telInput.val() && !that.telInput.prop("readonly") && that.selectedCountryData.dialCode) {
43017					// insert the dial code
43018					that.telInput.val("+" + that.selectedCountryData.dialCode);
43019					// after auto-inserting a dial code, if the first key they hit is '+' then assume they are entering a new number, so remove the dial code. use keypress instead of keydown because keydown gets triggered for the shift key (required to hit the + key), and instead of keyup because that shows the new '+' before removing the old one
43020					that.telInput.one("keypress.plus" + that.ns, function(e) {
43021						if (e.which == keys.PLUS) {
43022							that.telInput.val("");
43023						}
43024					});
43025					// after tabbing in, make sure the cursor is at the end we must use setTimeout to get outside of the focus handler as it seems the selection happens after that
43026					setTimeout(function() {
43027						var input = that.telInput[0];
43028						if (that.isGoodBrowser) {
43029							var len = that.telInput.val().length;
43030							input.setSelectionRange(len, len);
43031						}
43032					});
43033				}
43034			});
43035			// on blur or form submit: if just a dial code then remove it
43036			var form = this.telInput.prop("form");
43037			if (form) {
43038				$(form).on("submit" + this.ns, function() {
43039					that._removeEmptyDialCode();
43040				});
43041			}
43042			this.telInput.on("blur" + this.ns, function() {
43043				that._removeEmptyDialCode();
43044			});
43045		},
43046		_removeEmptyDialCode: function() {
43047			var value = this.telInput.val(), startsPlus = value.charAt(0) == "+";
43048			if (startsPlus) {
43049				var numeric = this._getNumeric(value);
43050				// if just a plus, or if just a dial code
43051				if (!numeric || this.selectedCountryData.dialCode == numeric) {
43052					this.telInput.val("");
43053				}
43054			}
43055			// remove the keypress listener we added on focus
43056			this.telInput.off("keypress.plus" + this.ns);
43057		},
43058		// extract the numeric digits from the given string
43059		_getNumeric: function(s) {
43060			return s.replace(/\D/g, "");
43061		},
43062		// show the dropdown
43063		_showDropdown: function() {
43064			this._setDropdownPosition();
43065			// update highlighting and scroll to active list item
43066			var activeListItem = this.countryList.children(".active");
43067			if (activeListItem.length) {
43068				this._highlightListItem(activeListItem);
43069				this._scrollTo(activeListItem);
43070			}
43071			// bind all the dropdown-related listeners: mouseover, click, click-off, keydown
43072			this._bindDropdownListeners();
43073			// update the arrow
43074			this.selectedFlagInner.children(".iti-arrow").addClass("up");
43075			this.telInput.trigger("open:countrydropdown");
43076		},
43077		// decide where to position dropdown (depends on position within viewport, and scroll)
43078		_setDropdownPosition: function() {
43079			var that = this;
43080			if (this.options.dropdownContainer) {
43081				this.dropdown.appendTo(this.options.dropdownContainer);
43082			}
43083			// show the menu and grab the dropdown height
43084			this.dropdownHeight = this.countryList.removeClass("hide").outerHeight();
43085			if (!this.isMobile) {
43086				var pos = this.telInput.offset(), inputTop = pos.top, windowTop = $(window).scrollTop(), // dropdownFitsBelow = (dropdownBottom < windowBottom)
43087					dropdownFitsBelow = inputTop + this.telInput.outerHeight() + this.dropdownHeight < windowTop + $(window).height(), dropdownFitsAbove = inputTop - this.dropdownHeight > windowTop;
43088				// by default, the dropdown will be below the input. If we want to position it above the input, we add the dropup class.
43089				this.countryList.toggleClass("dropup", !dropdownFitsBelow && dropdownFitsAbove);
43090				// if dropdownContainer is enabled, calculate postion
43091				if (this.options.dropdownContainer) {
43092					// by default the dropdown will be directly over the input because it's not in the flow. If we want to position it below, we need to add some extra top value.
43093					var extraTop = !dropdownFitsBelow && dropdownFitsAbove ? 0 : this.telInput.innerHeight();
43094					// calculate placement
43095					this.dropdown.css({
43096						top: inputTop + extraTop,
43097						left: pos.left
43098					});
43099					// close menu on window scroll
43100					$(window).on("scroll" + this.ns, function() {
43101						that._closeDropdown();
43102					});
43103				}
43104			}
43105		},
43106		// we only bind dropdown listeners when the dropdown is open
43107		_bindDropdownListeners: function() {
43108			var that = this;
43109			// when mouse over a list item, just highlight that one
43110			// we add the class "highlight", so if they hit "enter" we know which one to select
43111			this.countryList.on("mouseover" + this.ns, ".country", function(e) {
43112				that._highlightListItem($(this));
43113			});
43114			// listen for country selection
43115			this.countryList.on("click" + this.ns, ".country", function(e) {
43116				that._selectListItem($(this));
43117			});
43118			// click off to close
43119			// (except when this initial opening click is bubbling up)
43120			// we cannot just stopPropagation as it may be needed to close another instance
43121			var isOpening = true;
43122			$("html").on("click" + this.ns, function(e) {
43123				if (!isOpening) {
43124					that._closeDropdown();
43125				}
43126				isOpening = false;
43127			});
43128			// listen for up/down scrolling, enter to select, or letters to jump to country name.
43129			// use keydown as keypress doesn't fire for non-char keys and we want to catch if they
43130			// just hit down and hold it to scroll down (no keyup event).
43131			// listen on the document because that's where key events are triggered if no input has focus
43132			var query = "", queryTimer = null;
43133			$(document).on("keydown" + this.ns, function(e) {
43134				// prevent down key from scrolling the whole page,
43135				// and enter key from submitting a form etc
43136				e.preventDefault();
43137				if (e.which == keys.UP || e.which == keys.DOWN) {
43138					// up and down to navigate
43139					that._handleUpDownKey(e.which);
43140				} else if (e.which == keys.ENTER) {
43141					// enter to select
43142					that._handleEnterKey();
43143				} else if (e.which == keys.ESC) {
43144					// esc to close
43145					that._closeDropdown();
43146				} else if (e.which >= keys.A && e.which <= keys.Z || e.which == keys.SPACE) {
43147					// upper case letters (note: keyup/keydown only return upper case letters)
43148					// jump to countries that start with the query string
43149					if (queryTimer) {
43150						clearTimeout(queryTimer);
43151					}
43152					query += String.fromCharCode(e.which);
43153					that._searchForCountry(query);
43154					// if the timer hits 1 second, reset the query
43155					queryTimer = setTimeout(function() {
43156						query = "";
43157					}, 1e3);
43158				}
43159			});
43160		},
43161		// highlight the next/prev item in the list (and ensure it is visible)
43162		_handleUpDownKey: function(key) {
43163			var current = this.countryList.children(".highlight").first();
43164			var next = key == keys.UP ? current.prev() : current.next();
43165			if (next.length) {
43166				// skip the divider
43167				if (next.hasClass("divider")) {
43168					next = key == keys.UP ? next.prev() : next.next();
43169				}
43170				this._highlightListItem(next);
43171				this._scrollTo(next);
43172			}
43173		},
43174		// select the currently highlighted item
43175		_handleEnterKey: function() {
43176			var currentCountry = this.countryList.children(".highlight").first();
43177			if (currentCountry.length) {
43178				this._selectListItem(currentCountry);
43179			}
43180		},
43181		// find the first list item whose name starts with the query string
43182		_searchForCountry: function(query) {
43183			for (var i = 0; i < this.countries.length; i++) {
43184				if (this._startsWith(this.countries[i].name, query)) {
43185					var listItem = this.countryList.children("[data-country-code=" + this.countries[i].iso2 + "]").not(".preferred");
43186					// update highlighting and scroll
43187					this._highlightListItem(listItem);
43188					this._scrollTo(listItem, true);
43189					break;
43190				}
43191			}
43192		},
43193		// check if (uppercase) string a starts with string b
43194		_startsWith: function(a, b) {
43195			return a.substr(0, b.length).toUpperCase() == b;
43196		},
43197		// update the input's value to the given val (format first if possible)
43198		// NOTE: this is called from _setInitialState, handleUtils and setNumber
43199		_updateValFromNumber: function(number) {
43200			if (this.options.formatOnDisplay && window.intlTelInputUtils && this.selectedCountryData) {
43201				var format = !this.options.separateDialCode && (this.options.nationalMode || number.charAt(0) != "+") ? intlTelInputUtils.numberFormat.NATIONAL : intlTelInputUtils.numberFormat.INTERNATIONAL;
43202				number = intlTelInputUtils.formatNumber(number, this.selectedCountryData.iso2, format);
43203			}
43204			number = this._beforeSetNumber(number);
43205			this.telInput.val(number);
43206		},
43207		// check if need to select a new flag based on the given number
43208		// Note: called from _setInitialState, keyup handler, setNumber
43209		_updateFlagFromNumber: function(number) {
43210			// if we're in nationalMode and we already have US/Canada selected, make sure the number starts with a +1 so _getDialCode will be able to extract the area code
43211			// update: if we dont yet have selectedCountryData, but we're here (trying to update the flag from the number), that means we're initialising the plugin with a number that already has a dial code, so fine to ignore this bit
43212			if (number && this.options.nationalMode && this.selectedCountryData.dialCode == "1" && number.charAt(0) != "+") {
43213				if (number.charAt(0) != "1") {
43214					number = "1" + number;
43215				}
43216				number = "+" + number;
43217			}
43218			// try and extract valid dial code from input
43219			var dialCode = this._getDialCode(number), countryCode = null, numeric = this._getNumeric(number);
43220			if (dialCode) {
43221				// check if one of the matching countries is already selected
43222				var countryCodes = this.countryCodes[this._getNumeric(dialCode)], alreadySelected = $.inArray(this.selectedCountryData.iso2, countryCodes) > -1, // check if the given number contains a NANP area code i.e. the only dialCode that could be extracted was +1 (instead of say +1204) and the actual number's length is >=4
43223					isNanpAreaCode = dialCode == "+1" && numeric.length >= 4, nanpSelected = this.selectedCountryData.dialCode == "1";
43224				// only update the flag if:
43225				// A) NOT (we currently have a NANP flag selected, and the number is a regionlessNanp)
43226				// AND
43227				// B) either a matching country is not already selected OR the number contains a NANP area code (ensure the flag is set to the first matching country)
43228				if (!(nanpSelected && this._isRegionlessNanp(numeric)) && (!alreadySelected || isNanpAreaCode)) {
43229					// if using onlyCountries option, countryCodes[0] may be empty, so we must find the first non-empty index
43230					for (var j = 0; j < countryCodes.length; j++) {
43231						if (countryCodes[j]) {
43232							countryCode = countryCodes[j];
43233							break;
43234						}
43235					}
43236				}
43237			} else if (number.charAt(0) == "+" && numeric.length) {
43238				// invalid dial code, so empty
43239				// Note: use getNumeric here because the number has not been formatted yet, so could contain bad chars
43240				countryCode = "";
43241			} else if (!number || number == "+") {
43242				// empty, or just a plus, so default
43243				countryCode = this.defaultCountry;
43244			}
43245			if (countryCode !== null) {
43246				return this._setFlag(countryCode);
43247			}
43248			return false;
43249		},
43250		// check if the given number is a regionless NANP number (expects the number to contain an international dial code)
43251		_isRegionlessNanp: function(number) {
43252			var numeric = this._getNumeric(number);
43253			if (numeric.charAt(0) == "1") {
43254				var areaCode = numeric.substr(1, 3);
43255				return $.inArray(areaCode, regionlessNanpNumbers) > -1;
43256			}
43257			return false;
43258		},
43259		// remove highlighting from other list items and highlight the given item
43260		_highlightListItem: function(listItem) {
43261			this.countryListItems.removeClass("highlight");
43262			listItem.addClass("highlight");
43263		},
43264		// find the country data for the given country code
43265		// the ignoreOnlyCountriesOption is only used during init() while parsing the onlyCountries array
43266		_getCountryData: function(countryCode, ignoreOnlyCountriesOption, allowFail) {
43267			var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries;
43268			for (var i = 0; i < countryList.length; i++) {
43269				if (countryList[i].iso2 == countryCode) {
43270					return countryList[i];
43271				}
43272			}
43273			if (allowFail) {
43274				return null;
43275			} else {
43276				throw new Error("No country data for '" + countryCode + "'");
43277			}
43278		},
43279		// select the given flag, update the placeholder and the active list item
43280		// Note: called from _setInitialState, _updateFlagFromNumber, _selectListItem, setCountry
43281		_setFlag: function(countryCode) {
43282			var prevCountry = this.selectedCountryData.iso2 ? this.selectedCountryData : {};
43283			// do this first as it will throw an error and stop if countryCode is invalid
43284			this.selectedCountryData = countryCode ? this._getCountryData(countryCode, false, false) : {};
43285			// update the defaultCountry - we only need the iso2 from now on, so just store that
43286			if (this.selectedCountryData.iso2) {
43287				this.defaultCountry = this.selectedCountryData.iso2;
43288			}
43289			this.selectedFlagInner.attr("class", "iti-flag " + countryCode);
43290			// update the selected country's title attribute
43291			var title = countryCode ? this.selectedCountryData.name + ": +" + this.selectedCountryData.dialCode : "Unknown";
43292			this.selectedFlagInner.parent().attr("title", title);
43293			if (this.options.separateDialCode) {
43294				var dialCode = this.selectedCountryData.dialCode ? "+" + this.selectedCountryData.dialCode : "", parent = this.telInput.parent();
43295				if (prevCountry.dialCode) {
43296					parent.removeClass("iti-sdc-" + (prevCountry.dialCode.length + 1));
43297				}
43298				if (dialCode) {
43299					parent.addClass("iti-sdc-" + dialCode.length);
43300				}
43301				this.selectedDialCode.text(dialCode);
43302			}
43303			// and the input's placeholder
43304			this._updatePlaceholder();
43305			// update the active list item
43306			this.countryListItems.removeClass("active");
43307			if (countryCode) {
43308				this.countryListItems.find(".iti-flag." + countryCode).first().closest(".country").addClass("active");
43309			}
43310			// return if the flag has changed or not
43311			return prevCountry.iso2 !== countryCode;
43312		},
43313		// update the input placeholder to an example number from the currently selected country
43314		_updatePlaceholder: function() {
43315			var shouldSetPlaceholder = this.options.autoPlaceholder === "aggressive" || !this.hadInitialPlaceholder && (this.options.autoPlaceholder === true || this.options.autoPlaceholder === "polite");
43316			if (window.intlTelInputUtils && shouldSetPlaceholder) {
43317				var numberType = intlTelInputUtils.numberType[this.options.placeholderNumberType], placeholder = this.selectedCountryData.iso2 ? intlTelInputUtils.getExampleNumber(this.selectedCountryData.iso2, this.options.nationalMode, numberType) : "";
43318				placeholder = this._beforeSetNumber(placeholder);
43319				if (typeof this.options.customPlaceholder === "function") {
43320					placeholder = this.options.customPlaceholder(placeholder, this.selectedCountryData);
43321				}
43322				this.telInput.attr("placeholder", placeholder);
43323			}
43324		},
43325		// called when the user selects a list item from the dropdown
43326		_selectListItem: function(listItem) {
43327			// update selected flag and active list item
43328			var flagChanged = this._setFlag(listItem.attr("data-country-code"));
43329			this._closeDropdown();
43330			this._updateDialCode(listItem.attr("data-dial-code"), true);
43331			// focus the input
43332			this.telInput.focus();
43333			// put cursor at end - this fix is required for FF and IE11 (with nationalMode=false i.e. auto inserting dial code), who try to put the cursor at the beginning the first time
43334			if (this.isGoodBrowser) {
43335				var len = this.telInput.val().length;
43336				this.telInput[0].setSelectionRange(len, len);
43337			}
43338			if (flagChanged) {
43339				this._triggerCountryChange();
43340			}
43341		},
43342		// close the dropdown and unbind any listeners
43343		_closeDropdown: function() {
43344			this.countryList.addClass("hide");
43345			// update the arrow
43346			this.selectedFlagInner.children(".iti-arrow").removeClass("up");
43347			// unbind key events
43348			$(document).off(this.ns);
43349			// unbind click-off-to-close
43350			$("html").off(this.ns);
43351			// unbind hover and click listeners
43352			this.countryList.off(this.ns);
43353			// remove menu from container
43354			if (this.options.dropdownContainer) {
43355				if (!this.isMobile) {
43356					$(window).off("scroll" + this.ns);
43357				}
43358				this.dropdown.detach();
43359			}
43360			this.telInput.trigger("close:countrydropdown");
43361		},
43362		// check if an element is visible within it's container, else scroll until it is
43363		_scrollTo: function(element, middle) {
43364			var container = this.countryList, containerHeight = container.height(), containerTop = container.offset().top, containerBottom = containerTop + containerHeight, elementHeight = element.outerHeight(), elementTop = element.offset().top, elementBottom = elementTop + elementHeight, newScrollTop = elementTop - containerTop + container.scrollTop(), middleOffset = containerHeight / 2 - elementHeight / 2;
43365			if (elementTop < containerTop) {
43366				// scroll up
43367				if (middle) {
43368					newScrollTop -= middleOffset;
43369				}
43370				container.scrollTop(newScrollTop);
43371			} else if (elementBottom > containerBottom) {
43372				// scroll down
43373				if (middle) {
43374					newScrollTop += middleOffset;
43375				}
43376				var heightDifference = containerHeight - elementHeight;
43377				container.scrollTop(newScrollTop - heightDifference);
43378			}
43379		},
43380		// replace any existing dial code with the new one
43381		// Note: called from _selectListItem and setCountry
43382		_updateDialCode: function(newDialCode, hasSelectedListItem) {
43383			var inputVal = this.telInput.val(), newNumber;
43384			// save having to pass this every time
43385			newDialCode = "+" + newDialCode;
43386			if (inputVal.charAt(0) == "+") {
43387				// there's a plus so we're dealing with a replacement (doesn't matter if nationalMode or not)
43388				var prevDialCode = this._getDialCode(inputVal);
43389				if (prevDialCode) {
43390					// current number contains a valid dial code, so replace it
43391					newNumber = inputVal.replace(prevDialCode, newDialCode);
43392				} else {
43393					// current number contains an invalid dial code, so ditch it
43394					// (no way to determine where the invalid dial code ends and the rest of the number begins)
43395					newNumber = newDialCode;
43396				}
43397			} else if (this.options.nationalMode || this.options.separateDialCode) {
43398				// don't do anything
43399				return;
43400			} else {
43401				// nationalMode is disabled
43402				if (inputVal) {
43403					// there is an existing value with no dial code: prefix the new dial code
43404					newNumber = newDialCode + inputVal;
43405				} else if (hasSelectedListItem || !this.options.autoHideDialCode) {
43406					// no existing value and either they've just selected a list item, or autoHideDialCode is disabled: insert new dial code
43407					newNumber = newDialCode;
43408				} else {
43409					return;
43410				}
43411			}
43412			this.telInput.val(newNumber);
43413		},
43414		// try and extract a valid international dial code from a full telephone number
43415		// Note: returns the raw string inc plus character and any whitespace/dots etc
43416		_getDialCode: function(number) {
43417			var dialCode = "";
43418			// only interested in international numbers (starting with a plus)
43419			if (number.charAt(0) == "+") {
43420				var numericChars = "";
43421				// iterate over chars
43422				for (var i = 0; i < number.length; i++) {
43423					var c = number.charAt(i);
43424					// if char is number
43425					if ($.isNumeric(c)) {
43426						numericChars += c;
43427						// if current numericChars make a valid dial code
43428						if (this.countryCodes[numericChars]) {
43429							// store the actual raw string (useful for matching later)
43430							dialCode = number.substr(0, i + 1);
43431						}
43432						// longest dial code is 4 chars
43433						if (numericChars.length == 4) {
43434							break;
43435						}
43436					}
43437				}
43438			}
43439			return dialCode;
43440		},
43441		// get the input val, adding the dial code if separateDialCode is enabled
43442		_getFullNumber: function() {
43443			var val = $.trim(this.telInput.val()), dialCode = this.selectedCountryData.dialCode, prefix, numericVal = this._getNumeric(val), // normalized means ensure starts with a 1, so we can match against the full dial code
43444				normalizedVal = numericVal.charAt(0) == "1" ? numericVal : "1" + numericVal;
43445			if (this.options.separateDialCode) {
43446				prefix = "+" + dialCode;
43447			} else if (val.charAt(0) != "+" && val.charAt(0) != "1" && dialCode && dialCode.charAt(0) == "1" && dialCode.length == 4 && dialCode != normalizedVal.substr(0, 4)) {
43448				// if the user has entered a national NANP number, then ensure it includes the full dial code / area code
43449				prefix = dialCode.substr(1);
43450			} else {
43451				prefix = "";
43452			}
43453			return prefix + val;
43454		},
43455		// remove the dial code if separateDialCode is enabled
43456		_beforeSetNumber: function(number) {
43457			if (this.options.separateDialCode) {
43458				var dialCode = this._getDialCode(number);
43459				if (dialCode) {
43460					// US dialCode is "+1", which is what we want
43461					// CA dialCode is "+1 123", which is wrong - should be "+1" (as it has multiple area codes)
43462					// AS dialCode is "+1 684", which is what we want
43463					// Solution: if the country has area codes, then revert to just the dial code
43464					if (this.selectedCountryData.areaCodes !== null) {
43465						dialCode = "+" + this.selectedCountryData.dialCode;
43466					}
43467					// a lot of numbers will have a space separating the dial code and the main number, and some NANP numbers will have a hyphen e.g. +1 684-733-1234 - in both cases we want to get rid of it
43468					// NOTE: don't just trim all non-numerics as may want to preserve an open parenthesis etc
43469					var start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
43470					number = number.substr(start);
43471				}
43472			}
43473			return this._cap(number);
43474		},
43475		// trigger the 'countrychange' event
43476		_triggerCountryChange: function() {
43477			this.telInput.trigger("countrychange", this.selectedCountryData);
43478		},
43479		/**************************
43480		 *  SECRET PUBLIC METHODS
43481		 **************************/
43482		// this is called when the geoip call returns
43483		handleAutoCountry: function() {
43484			if (this.options.initialCountry === "auto") {
43485				// we must set this even if there is an initial val in the input: in case the initial val is invali
43485d and they delete it - they should see their auto country
43486				this.defaultCountry = $.fn[pluginName].autoCountry;
43487				// if there's no initial value in the input, then update the flag
43488				if (!this.telInput.val()) {
43489					this.setCountry(this.defaultCountry);
43490				}
43491				this.autoCountryDeferred.resolve();
43492			}
43493		},
43494		// this is called when the utils request completes
43495		handleUtils: function() {
43496			// if the request was successful
43497			if (window.intlTelInputUtils) {
43498				// if there's an initial value in the input, then format it
43499				if (this.telInput.val()) {
43500					this._updateValFromNumber(this.telInput.val());
43501				}
43502				this._updatePlaceholder();
43503			}
43504			this.utilsScriptDeferred.resolve();
43505		},
43506		/********************
43507		 *  PUBLIC METHODS
43508		 ********************/
43509		// remove plugin
43510		destroy: function() {
43511			if (this.allowDropdown) {
43512				// make sure the dropdown is closed (and unbind listeners)
43513				this._closeDropdown();
43514				// click event to open dropdown
43515				this.selectedFlagInner.parent().off(this.ns);
43516				// label click hack
43517				this.telInput.closest("label").off(this.ns);
43518			}
43519			// unbind submit event handler on form
43520			if (this.options.autoHideDialCode) {
43521				var form = this.telInput.prop("form");
43522				if (form) {
43523					$(form).off(this.ns);
43524				}
43525			}
43526			// unbind all events: key events, and focus/blur events if autoHideDialCode=true
43527			this.telInput.off(this.ns);
43528			// remove markup (but leave the original input)
43529			var container = this.telInput.parent();
43530			container.before(this.telInput).remove();
43531		},
43532		// get the extension from the current number
43533		getExtension: function() {
43534			if (window.intlTelInputUtils) {
43535				return intlTelInputUtils.getExtension(this._getFullNumber(), this.selectedCountryData.iso2);
43536			}
43537			return "";
43538		},
43539		// format the number to the given format
43540		getNumber: function(format) {
43541			if (window.intlTelInputUtils) {
43542				return intlTelInputUtils.formatNumber(this._getFullNumber(), this.selectedCountryData.iso2, format);
43543			}
43544			return "";
43545		},
43546		// get the type of the entered number e.g. landline/mobile
43547		getNumberType: function() {
43548			if (window.intlTelInputUtils) {
43549				return intlTelInputUtils.getNumberType(this._getFullNumber(), this.selectedCountryData.iso2);
43550			}
43551			return -99;
43552		},
43553		// get the country data for the currently selected flag
43554		getSelectedCountryData: function() {
43555			return this.selectedCountryData;
43556		},
43557		// get the validation error
43558		getValidationError: function() {
43559			if (window.intlTelInputUtils) {
43560				return intlTelInputUtils.getValidationError(this._getFullNumber(), this.selectedCountryData.iso2);
43561			}
43562			return -99;
43563		},
43564		// validate the input val - assumes the global function isValidNumber (from utilsScript)
43565		isValidNumber: function() {
43566			var val = $.trim(this._getFullNumber()), countryCode = this.options.nationalMode ? this.selectedCountryData.iso2 : "";
43567			return window.intlTelInputUtils ? intlTelInputUtils.isValidNumber(val, countryCode) : null;
43568		},
43569		// update the selected flag, and update the input val accordingly
43570		setCountry: function(countryCode) {
43571			countryCode = countryCode.toLowerCase();
43572			// check if already selected
43573			if (!this.selectedFlagInner.hasClass(countryCode)) {
43574				this._setFlag(countryCode);
43575				this._updateDialCode(this.selectedCountryData.dialCode, false);
43576				this._triggerCountryChange();
43577			}
43578		},
43579		// set the input value and update the flag
43580		setNumber: function(number) {
43581			// we must update the flag first, which updates this.selectedCountryData, which is used for formatting the number before displaying it
43582			var flagChanged = this._updateFlagFromNumber(number);
43583			this._updateValFromNumber(number);
43584			if (flagChanged) {
43585				this._triggerCountryChange();
43586			}
43587		}
43588	};
43589	// using https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate
43590	// (adapted to allow public functions)
43591	$.fn[pluginName] = function(options) {
43592		var args = arguments;
43593		// Is the first parameter an object (options), or was omitted,
43594		// instantiate a new instance of the plugin.
43595		if (options === undefined || typeof options === "object") {
43596			// collect all of the deferred objects for all instances created with this selector
43597			var deferreds = [];
43598			this.each(function() {
43599				if (!$.data(this, "plugin_" + pluginName)) {
43600					var instance = new Plugin(this, options);
43601					var instanceDeferreds = instance._init();
43602					// we now have 2 deffereds: 1 for auto country, 1 for utils script
43603					deferreds.push(instanceDeferreds[0]);
43604					deferreds.push(instanceDeferreds[1]);
43605					$.data(this, "plugin_" + pluginName, instance);
43606				}
43607			});
43608			// return the promise from the "master" deferred object that tracks all the others
43609			return $.when.apply(null, deferreds);
43610		} else if (typeof options === "string" && options[0] !== "_") {
43611			// If the first parameter is a string and it doesn't start
43612			// with an underscore or "contains" the `init`-function,
43613			// treat this as a call to a public method.
43614			// Cache the method call to make it possible to return a value
43615			var returns;
43616			this.each(function() {
43617				var instance = $.data(this, "plugin_" + pluginName);
43618				// Tests that there's already a plugin-instance
43619				// and checks that the requested public method exists
43620				if (instance instanceof Plugin && typeof instance[options] === "function") {
43621					// Call the method of our plugin instance,
43622					// and pass it the supplied arguments.
43623					returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
43624				}
43625				// Allow instances to be destroyed via the 'destroy' method
43626				if (options === "destroy") {
43627					$.data(this, "plugin_" + pluginName, null);
43628				}
43629			});
43630			// If the earlier cached method gives a value back return the value,
43631			// otherwise return this to preserve chainability.
43632			return returns !== undefined ? returns : this;
43633		}
43634	};
43635	/********************
43636	 *  STATIC METHODS
43637	 ********************/
43638	// get the country data object
43639	$.fn[pluginName].getCountryData = function() {
43640		return allCountries;
43641	};
43642	// load the utils script
43643	$.fn[pluginName].loadUtils = function(path, utilsScriptDeferred) {
43644		if (!$.fn[pluginName].loadedUtilsScript) {
43645			// don't do this twice! (dont just check if window.intlTelInputUtils exists as if init plugin multiple times in quick succession, it may not have finished loading yet)
43646			$.fn[pluginName].loadedUtilsScript = true;
43647			// dont use $.getScript as it prevents caching
43648			$.ajax({
43649				type: "GET",
43650				url: path,
43651				complete: function() {
43652					// tell all instances that the utils request is complete
43653					$(".intl-tel-input input").intlTelInput("handleUtils");
43654				},
43655				dataType: "script",
43656				cache: true
43657			});
43658		} else if (utilsScriptDeferred) {
43659			utilsScriptDeferred.resolve();
43660		}
43661	};
43662	// default options
43663	$.fn[pluginName].defaults = defaults;
43664	// version
43665	$.fn[pluginName].version = "12.0.2";
43666	// Array of country objects for the flag dropdown.
43667	// Here is the criteria for the plugin to support a given country/territory
43668	// - It has an iso2 code: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
43669	// - It has it's own country calling code (it is not a sub-region of another country): https://en.wikipedia.org/wiki/List_of_country_calling_codes
43670	// - It has a flag in the region-flags project: https://github.com/behdad/region-flags/tree/gh-pages/png
43671	// - It is supported by libphonenumber (it must be listed on this page): https://github.com/googlei18n/libphonenumber/blob/master/resources/ShortNumberMetadata.xml
43672	// Each country array has the following information:
43673	// [
43674	//    Country name,
43675	//    iso2 code,
43676	//    International dial code,
43677	//    Order (if >1 country with same dial code),
43678	//    Area codes
43679	// ]
43680	var allCountries = [ [ "Afghanistan (‫افغانستان‬‎)", "af", "93" ], [ "Albania (Shqipëri)", "al", "355" ], [ "Algeria (‫الجزائر‬‎)", "dz", "213" ], [ "American Samoa", "as", "1684" ], [ "Andorra", "ad", "376" ], [ "Angola", "ao", "244" ], [ "Anguilla", "ai", "1264" ], [ "Antigua and Barbuda", "ag", "1268" ], [ "Argentina", "ar", "54" ], [ "Armenia (Հայաստան)", "am", "374" ], [ "Aruba", "aw", "297" ], [ "Australia", "au", "61", 0 ], [ "Austria (Österreich)", "at", "43" ], [ "Azerbaijan (Azərbaycan)", "az", "994" ], [ "Bahamas", "bs", "1242" ], [ "Bahrain (‫البحرين‬‎)", "bh", "973" ], [ "Bangladesh (বাংলাদেশ)", "bd", "880" ], [ "Barbados", "bb", "1246" ], [ "Belarus (Беларусь)", "by", "375" ], [ "Belgium (België)", "be", "32" ], [ "Belize", "bz", "501" ], [ "Benin (Bénin)", "bj", "229" ], [ "Bermuda", "bm", "1441" ], [ "Bhutan (འབྲུག)", "bt", "975" ], [ "Bolivia", "bo", "591" ], [ "Bosnia and Herzegovina (Босна и Херцеговина)", "ba", "387" ], [ "Botswana", "bw", "267" ], [ "Brazil (Brasil)", "br", "55" ], [ "British Indian Ocean Territory", "io", "246" ], [ "British Virgin Islands", "vg", "1284" ], [ "Brunei", "bn", "673" ], [ "Bulgaria (България)", "bg", "359" ], [ "Burkina Faso", "bf", "226" ], [ "Burundi (Uburundi)", "bi", "257" ], [ "Cambodia (កម្ពុជា)", "kh", "855" ], [ "Cameroon (Cameroun)", "cm", "237" ], [ "Canada", "ca", "1", 1, [ "204", "226", "236", "249", "250", "289", "306", "343", "365", "387", "403", "416", "418", "431", "437", "438", "450", "506", "514", "519", "548", "579", "581", "587", "604", "613", "639", "647", "672", "705", "709", "742", "778", "780", "782", "807", "819", "825", "867", "873", "902", "905" ] ], [ "Cape Verde (Kabu Verdi)", "cv", "238" ], [ "Caribbean Netherlands", "bq", "599", 1 ], [ "Cayman Islands", "ky", "1345" ], [ "Central African Republic (République centrafricaine)", "cf", "236" ], [ "Chad (Tchad)", "td", "235" ], [ "Chile", "cl", "56" ], [ "China (中国)", "cn", "86" ], [ "Christmas Island", "cx", "61", 2 ], [ "Cocos (Keeling) Islands", "cc", "61", 1 ], [ "Colombia", "co", "57" ], [ "Comoros (‫جزر القمر‬‎)", "km", "269" ], [ "Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)", "cd", "243" ], [ "Congo (Republic) (Congo-Brazzaville)", "cg", "242" ], [ "Cook Islands", "ck", "682" ], [ "Costa Rica", "cr", "506" ], [ "Côte d’Ivoire", "ci", "225" ], [ "Croatia (Hrvatska)", "hr", "385" ], [ "Cuba", "cu", "53" ], [ "Curaçao", "cw", "599", 0 ], [ "Cyprus (Κύπρος)", "cy", "357" ], [ "Czech Republic (Česká republika)", "cz", "420" ], [ "Denmark (Danmark)", "dk", "45" ], [ "Djibouti", "dj", "253" ], [ "Dominica", "dm", "1767" ], [ "Dominican Republic (República Dominicana)", "do", "1", 2, [ "809", "829", "849" ] ], [ "Ecuador", "ec", "593" ], [ "Egypt (‫مصر‬‎)", "eg", "20" ], [ "El Salvador", "sv", "503" ], [ "Equatorial Guinea (Guinea Ecuatorial)", "gq", "240" ], [ "Eritrea", "er", "291" ], [ "Estonia (Eesti)", "ee", "372" ], [ "Ethiopia", "et", "251" ], [ "Falkland Islands (Islas Malvinas)", "fk", "500" ], [ "Faroe Islands (Føroyar)", "fo", "298" ], [ "Fiji", "fj", "679" ], [ "Finland (Suomi)", "fi", "358", 0 ], [ "France", "fr", "33" ], [ "French Guiana (Guyane française)", "gf", "594" ], [ "French Polynesia (Polynésie française)", "pf", "689" ], [ "Gabon", "ga", "241" ], [ "Gambia", "gm", "220" ], [ "Georgia (საქართველო)", "ge", "995" ], [ "Germany (Deutschland)", "de", "49" ], [ "Ghana (Gaana)", "gh", "233" ], [ "Gibraltar", "gi", "350" ], [ "Greece (Ελλάδα)", "gr", "30" ], [ "Greenland (Kalaallit Nun
43680aat)", "gl", "299" ], [ "Grenada", "gd", "1473" ], [ "Guadeloupe", "gp", "590", 0 ], [ "Guam", "gu", "1671" ], [ "Guatemala", "gt", "502" ], [ "Guernsey", "gg", "44", 1 ], [ "Guinea (Guinée)", "gn", "224" ], [ "Guinea-Bissau (Guiné Bissau)", "gw", "245" ], [ "Guyana", "gy", "592" ], [ "Haiti", "ht", "509" ], [ "Honduras", "hn", "504" ], [ "Hong Kong (香港)", "hk", "852" ], [ "Hungary (Magyarország)", "hu", "36" ], [ "Iceland (Ísland)", "is", "354" ], [ "India (भारत)", "in", "91" ], [ "Indonesia", "id", "62" ], [ "Iran (‫ایران‬‎)", "ir", "98" ], [ "Iraq (‫العراق‬‎)", "iq", "964" ], [ "Ireland", "ie", "353" ], [ "Isle of Man", "im", "44", 2 ], [ "Israel (‫ישראל‬‎)", "il", "972" ], [ "Italy (Italia)", "it", "39", 0 ], [ "Jamaica", "jm", "1876" ], [ "Japan (日本)", "jp", "81" ], [ "Jersey", "je", "44", 3 ], [ "Jordan (‫الأردن‬‎)", "jo", "962" ], [ "Kazakhstan (Казахстан)", "kz", "7", 1 ], [ "Kenya", "ke", "254" ], [ "Kiribati", "ki", "686" ], [ "Kosovo", "xk", "383" ], [ "Kuwait (‫الكويت‬‎)", "kw", "965" ], [ "Kyrgyzstan (Кыргызстан)", "kg", "996" ], [ "Laos (ລາວ)", "la", "856" ], [ "Latvia (Latvija)", "lv", "371" ], [ "Lebanon (‫لبنان‬‎)", "lb", "961" ], [ "Lesotho", "ls", "266" ], [ "Liberia", "lr", "231" ], [ "Libya (‫ليبيا‬‎)", "ly", "218" ], [ "Liechtenstein", "li", "423" ], [ "Lithuania (Lietuva)", "lt", "370" ], [ "Luxembourg", "lu", "352" ], [ "Macau (澳門)", "mo", "853" ], [ "Macedonia (FYROM) (Македонија)", "mk", "389" ], [ "Madagascar (Madagasikara)", "mg", "261" ], [ "Malawi", "mw", "265" ], [ "Malaysia", "my", "60" ], [ "Maldives", "mv", "960" ], [ "Mali", "ml", "223" ], [ "Malta", "mt", "356" ], [ "Marshall Islands", "mh", "692" ], [ "Martinique", "mq", "596" ], [ "Mauritania (‫موريتانيا‬‎)", "mr", "222" ], [ "Mauritius (Moris)", "mu", "230" ], [ "Mayotte", "yt", "262", 1 ], [ "Mexico (México)", "mx", "52" ], [ "Micronesia", "fm", "691" ], [ "Moldova (Republica Moldova)", "md", "373" ], [ "Monaco", "mc", "377" ], [ "Mongolia (Монгол)", "mn", "976" ], [ "Montenegro (Crna Gora)", "me", "382" ], [ "Montserrat", "ms", "1664" ], [ "Morocco (‫المغرب‬‎)", "ma", "212", 0 ], [ "Mozambique (Moçambique)", "mz", "258" ], [ "Myanmar (Burma) (မြန်မာ)", "mm", "95" ], [ "Namibia (Namibië)", "na", "264" ], [ "Nauru", "nr", "674" ], [ "Nepal (नेपाल)", "np", "977" ], [ "Netherlands (Nederland)", "nl", "31" ], [ "New Caledonia (Nouvelle-Calédonie)", "nc", "687" ], [ "New Zealand", "nz", "64" ], [ "Nicaragua", "ni", "505" ], [ "Niger (Nijar)", "ne", "227" ], [ "Nigeria", "ng", "234" ], [ "Niue", "nu", "683" ], [ "Norfolk Island", "nf", "672" ], [ "North Korea (조선 민주주의 인민 공화국)", "kp", "850" ], [ "Northern Mariana Islands", "mp", "1670" ], [ "Norway (Norge)", "no", "47", 0 ], [ "Oman (‫عُمان‬‎)", "om", "968" ], [ "Pakistan (‫پاکستان‬‎)", "pk", "92" ], [ "Palau", "pw", "680" ], [ "Palestine (‫فلسطين‬‎)", "ps", "970" ], [ "Panama (Panamá)", "pa", "507" ], [ "Papua New Guinea", "pg", "675" ], [ "Paraguay", "py", "595" ], [ "Peru (Perú)", "pe", "51" ], [ "Philippines", "ph", "63" ], [ "Poland (Polska)", "pl", "48" ], [ "Portugal", "pt", "351" ], [ "Puerto Rico", "pr", "1", 3, [ "787", "939" ] ], [ "Qatar (‫قطر‬‎)", "qa", "974" ], [ "Réunion (La Réunion)", "re", "262", 0 ], [ "Romania (România)", "ro", "40" ], [ "Russia (Россия)", "ru", "7", 0 ], [ "Rwanda", "rw", "250" ], [ "Saint Barthélemy", "bl", "590", 1 ], [ "Saint Helena", "sh", "290" ], [ "Saint Kitts and Nevis", "kn", "1869" ], [ "Saint Lucia", "lc", "1758" ], [ "Saint Martin (Saint-Martin (partie française))", "mf", "590", 2 ], [ "Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)", "pm", "508" ], [ "Saint Vincent and the Grenadines", "vc", "1784" ], [ "Samoa", "ws", "685" ], [ "San Marino", "sm", "378" ], [ "São Tomé and Príncipe (São Tomé e Príncipe)", "st", "239" ], [ "Saudi Arabia (‫المملكة العربية السعودية‬‎)", "sa", "966" ], [ "Senegal (Sénégal)", "sn", "221" ], [ "Serbia (Србија)", "rs", "381" ], [ "Seychelles", "sc", "248" ], [ "Sierra Leone", "sl", "232" ], [ "Singapore", "sg", "65" ], [ "Sint Maarten", "sx", "1721" ], [ "Slovakia (Slovensko)", "sk", "421" ], [ "Slovenia (Slovenija)", "si", "386" ], [ "Solomon Islands", "sb", "677" ], [ "Somalia (Soomaaliya)", "so", "252" ], [ "South Africa", "za", "27" ], [ "South Korea (대한민국)", "kr", "82" ], [ "South Sudan (‫جنوب السودان‬‎)", "ss", "211" ], [ "Spain (España)", "es", "34" ], [ "Sri Lanka (ශ්‍රී ලංකාව)", "lk", "94" ], [ "Sudan (‫السودان‬‎)", "sd", "249" ], [ "Suriname", "sr", "597" ], [ "Svalbard and Jan Mayen", "sj", "47", 1 ], [ "Swaziland", "sz", "268" ], [ "Sweden (Sverige)", "se", "46" ], [ "Switzerland (Schweiz)", "ch", "41" ], [ "Syria (‫سوريا‬‎)", "sy", "963" ], [ "Taiwan (台灣)", "tw", "886" ], [ "Tajikistan", "tj", "992" ], [ "Tanzania", "tz", "255" ], [ "Thailand (ไทย)", "th", "66" ], [ "Timor-Leste", "tl", "670" ], [ "Togo", "tg", "228" ], [ "Tokelau", "tk", "690" ], [ "Tonga", "to", "676" ], [ "Trinidad and Tobago", "tt", "1868" ], [ "Tunisia (‫تونس‬‎)", "tn", "216" ], [ "Turkey (Türkiye)", "tr", "90" ], [ "Turkmenistan", "tm", "993" ], [ "Turks and Caicos Islands", "tc", "1649" ], [ "Tuvalu", "tv", "688" ], [ "U.S. Virgin Islands", "vi", "1340" ], [ "Uganda", "ug", "256" ], [ "Ukraine (Україна)", "ua", "380" ], [ "United Arab Emirates (‫الإمارات العربية المتحدة‬‎)", "ae", "971" ], [ "United Kingdom", "gb", "44", 0 ], [ "United States", "us", "1", 0 ], [ "Uruguay", "uy", "598" ], [ "Uzbekistan (Oʻzbekiston)", "uz", "998" ], [ "Vanuatu", "vu", "678" ], [ "Vatican City (Città del Vaticano)", "va", "39", 1 ], [ "Venezuela", "ve", "58" ], [ "Vietnam (Việt Nam)", "vn", "84" ], [ "Wallis and Futuna (Wallis-et-Futuna)", "wf", "681" ], [ "Western Sahara (‫الصحراء الغربية‬‎)", "eh", "212", 1 ], [ "Yemen (‫اليمن‬‎)", "ye", "967" ], [ "Zambia", "zm", "260" ], [ "Zimbabwe", "zw", "263" ], [ "Åland Islands", "ax", "358", 1 ] ];
43681	// loop over all of the countries above
43682	for (var i = 0; i < allCountries.length; i++) {
43683		var c = allCountries[i];
43684		allCountries[i] = {
43685			name: c[0],
43686			iso2: c[1],
43687			dialCode: c[2],
43688			priority: c[3] || 0,
43689			areaCodes: c[4] || null
43690		};
43691	}
43692});
43693(function(){for(var aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},l="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this,m=["String","prototype","repeat"],n=0;n<m.length-1;n++){var p=m[n];p in l||(l[p]={});l=l[p]}
43694	var ba=m[m.length-1],r=l[ba],t=r?r:function(a){var b;if(null==this)throw new TypeError("The 'this' value for String.prototype.repeat must not be null or undefined");b=this+"";if(0>a||1342177279<a)throw new RangeError("Invalid count value");a|=0;for(var c="";a;)if(a&1&&(c+=b),a>>>=1)b+=b;return c};t!=r&&null!=t&&aa(l,ba,{configurable:!0,writable:!0,value:t});var ca=this;function u(a){return"string"==typeof a}
43695	function v(a,b){var c=a.split("."),d=ca;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d[e]?d=d[e]:d=d[e]={}:d[e]=b}function w(a,b){function c(){}c.prototype=b.prototype;a.aa=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.$=function(a,c,f){for(var d=Array(arguments.length-2),e=2;e<arguments.length;e++)d[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};var x=Array.prototype.indexOf?function(a,b,c){return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(u(a))return u(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};function y(a,b){a.sort(b||da)}function da(a,b){return a>b?1:a<b?-1:0};function ea(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};function fa(a,b){this.a=a;this.h=!!b.i;this.b=b.c;this.m=b.type;this.l=!1;switch(this.b){case ga:case ha:case ia:case ja:case ka:case la:case ma:this.l=!0}this.g=b.defaultValue}var ma=1,la=2,ga=3,ha=4,ia=6,ja=16,ka=18;
43695function na(a,b){this.b=a;this.a={};for(var c=0;c<b.length;c++){var d=b[c];this.a[d.a]=d}}function oa(a){a=ea(a.a);y(a,function(a,c){return a.a-c.a});return a};function A(){this.a={};this.g=this.f().a;this.b=this.h=null}A.prototype.has=function(a){return null!=this.a[a.a]};A.prototype.get=function(a,b){return B(this,a.a,b)};A.prototype.set=function(a,b){C(this,a.a,b)};
43696	function pa(a,b){for(var c=oa(a.f()),d=0;d<c.length;d++){var e=c[d],f=e.a;if(null!=b.a[f]){a.b&&delete a.b[e.a];var g=11==e.b||10==e.b;if(e.h)for(var e=D(b,f),h=0;h<e.length;h++){var k=a,q=f,z=g?e[h].clone():e[h];k.a[q]||(k.a[q]=[]);k.a[q].push(z);k.b&&delete k.b[q]}else e=E(b,f),g?(g=E(a,f))?pa(g,e):C(a,f,e.clone()):C(a,f,e)}}}A.prototype.clone=function(){var a=new this.constructor;a!=this&&(a.a={},a.b&&(a.b={}),pa(a,this));return a};
43697	function E(a,b){var c=a.a[b];if(null==c)return null;if(a.h){if(!(b in a.b)){var d=a.h,e=a.g[b];if(null!=c)if(e.h){for(var f=[],g=0;g<c.length;g++)f[g]=d.a(e,c[g]);c=f}else c=d.a(e,c);return a.b[b]=c}return a.b[b]}return c}function B(a,b,c){var d=E(a,b);return a.g[b].h?d[c||0]:d}function F(a,b){var c;if(null!=a.a[b])c=B(a,b,void 0);else a:{c=a.g[b];if(void 0===c.g){var d=c.m;if(d===Boolean)c.g=!1;else if(d===Number)c.g=0;else if(d===String)c.g=c.l?"0":"";else{c=new d;break a}}c=c.g}return c}
43698	function D(a,b){return E(a,b)||[]}function G(a,b){return a.g[b].h?null!=a.a[b]?a.a[b].length:0:null!=a.a[b]?1:0}function C(a,b,c){a.a[b]=c;a.b&&(a.b[b]=c)}function H(a,b){var c=[],d;for(d in b)0!=d&&c.push(new fa(d,b[d]));return new na(a,c)};function I(){}I.prototype.b=function(a){new a.b;throw Error("Unimplemented");};I.prototype.a=function(a,b){if(11==a.b||10==a.b)return b instanceof A?b:this.b(a.m.prototype.f(),b);if(14==a.b){if(u(b)&&qa.test(b)){var c=Number(b);if(0<c)return c}return b}if(!a.l)return b;c=a.m;if(c===String){if("number"==typeof b)return String(b)}else if(c===Number&&u(b)&&("Infinity"===b||"-Infinity"===b||"NaN"===b||qa.test(b)))return Number(b);return b};var qa=/^-?[0-9]+$/;function J(){}w(J,I);J.prototype.b=function(a,b){var c=new a.b;c.h=this;c.a=b;c.b={};return c};function ra(){}w(ra,J);ra.prototype.a=function(a,b){return 8==a.b?!!b:I.prototype.a.apply(this,arguments)};function K(a,b){null!=a&&this.a.apply(this,arguments)}K.prototype.b="";K.prototype.set=function(a){this.b=""+a};K.prototype.a=function(a,b,c){this.b+=String(a);if(null!=b)for(var d=1;d<arguments.length;d++)this.b+=arguments[d];return this};K.prototype.toString=function(){return this.b};/*
43699
43700 Protocol Buffer 2 Copyright 2008 Google Inc.
43701 All other code copyright its respective owners.
43702 Copyright (C) 2010 The Libphonenumber Authors
43703
43704 Licensed under the Apache License, Version 2.0 (the "License");
43705 you may not use this file except in compliance with the License.
43706 You may obtain a copy of the License at
43707
43708 http://www.apache.org/licenses/LICENSE-2.0
43709
43710 Unless required by applicable law or agreed to in writing, software
43711 distributed under the License is distributed on an "AS IS" BASIS,
43712 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43713 See the License for the specific language governing permissions and
43714 limitations under the License.
43715*/
43716	function L(){A.call(this)}w(L,A);var sa=null;function M(){A.call(this)}w(M,A);var ta=null;function N(){A.call(this)}w(N,A);var ua=null;
43717	L.prototype.f=function(){var a=sa;a||(sa=a=H(L,{0:{name:"NumberFormat",j:"i18n.phonenumbers.NumberFormat"},1:{name:"pattern",required:!0,c:9,type:String},2:{name:"format",required:!0,c:9,type:String},3:{name:"leading_digits_pattern",i:!0,c:9,type:String},4:{name:"national_prefix_formatting_rule",c:9,type:String},6:{name:"national_prefix_optional_when_formatting",c:8,defaultValue:!1,type:Boolean},5:{name:"domestic_carrier_code_formatting_rule",c:9,type:String}}));return a};L.f=L.prototype.f;
43718	M.prototype.f=function(){var a=ta;a||(ta=a=H(M,{0:{name:"PhoneNumberDesc",j:"i18n.phonenumbers.PhoneNumberDesc"},2:{name:"national_number_pattern",c:9,type:String},9:{name:"possible_length",i:!0,c:5,type:Number},10:{name:"possible_length_local_only",i:!0,c:5,type:Number},6:{name:"example_number",c:9,type:String}}));return a};M.f=M.prototype.f;
43719	N.prototype.f=function(){var a=ua;a||(ua=a=H(N,{0:{name:"PhoneMetadata",j:"i18n.phonenumbers.PhoneMetadata"},1:{name:"general_desc",c:11,type:M},2:{name:"fixed_line",c:11,type:M},3:{name:"mobile",c:11,type:M},4:{name:"toll_free",c:11,type:M},5:{name:"premium_rate",c:11,type:M},6:{name:"shared_cost",c:11,type:M},7:{name:"personal_number",c:11,type:M},8:{name:"voip",c:11,type:M},21:{name:"pager",c:11,type:M},25:{name:"uan",c:11,type:M},27:{name:"emergency",c:11,type:M},28:{name:"voicemail",c:11,type:M},
43720		24:{name:"no_international_dialling",c:11,type:M},9:{name:"id",required:!0,c:9,type:String},10:{name:"country_code",c:5,type:Number},11:{name:"international_prefix",c:9,type:String},17:{name:"preferred_international_prefix",c:9,type:String},12:{name:"national_prefix",c:9,type:String},13:{name:"preferred_extn_prefix",c:9,type:String},15:{name:"national_prefix_for_parsing",c:9,type:String},16:{name:"national_prefix_transform_rule",c:9,type:String},18:{name:"same_mobile_and_fixed_line_pattern",c:8,defaultValue:!1,
43721			type:Boolean},19:{name:"number_format",i:!0,c:11,type:L},20:{name:"intl_number_format",i:!0,c:11,type:L},22:{name:"main_country_for_code",c:8,defaultValue:!1,type:Boolean},23:{name:"leading_digits",c:9,type:String},26:{name:"leading_zero_possible",c:8,defaultValue:!1,type:Boolean}}));return a};N.f=N.prototype.f;function O(){A.call(this)}w(O,A);var va=null,wa={w:0,v:1,u:5,s:10,o:20};
43722	O.prototype.f=function(){var a=va;a||(va=a=H(O,{0:{name:"PhoneNumber",j:"i18n.phonenumbers.PhoneNumber"},1:{name:"country_code",required:!0,c:5,type:Number},2:{name:"national_number",required:!0,c:4,type:Number},3:{name:"extension",c:9,type:String},4:{name:"italian_leading_zero",c:8,type:Boolean},8:{name:"number_of_leading_zeros",c:5,defaultValue:1,type:Number},5:{name:"raw_input",c:9,type:String},6:{name:"country_code_source",c:14,defaultValue:0,type:wa},7:{name:"preferred_domestic_carrier_code",
43723			c:9,type:String}}));return a};O.ctor=O;O.ctor.f=O.prototype.f;/*
43724
43725 Copyright (C) 2010 The Libphonenumber Authors
43726
43727 Licensed under the Apache License, Version 2.0 (the "License");
43728 you may not use this file except in compliance with the License.
43729 You may obtain a copy of the License at
43730
43731 http://www.apache.org/licenses/LICENSE-2.0
43732
43733 Unless required by applicable law or agreed to in writing, software
43734 distributed under the License is distributed on an "AS IS" BASIS,
43735 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43736 See the License for the specific language governing permissions and
43737 limitations under the License.
43738*/
43739	var P={1:"US AG AI AS BB BM BS CA DM DO GD GU JM KN KY LC MP MS PR SX TC TT VC VG VI".split(" "),7:["RU","KZ"],20:["EG"],27:["ZA"],30:["GR"],31:["NL"],32:["BE"],33:["FR"],34:["ES"],36:["HU"],39:["IT","VA"],40:["RO"],41:["CH"],43:["AT"],44:["GB","GG","IM","JE"],45:["DK"],46:["SE"],47:["NO","SJ"],48:["PL"],49:["DE"],51:["PE"],52:["MX"],53:["CU"],54:["AR"],55:["BR"],56:["CL"],57:["CO"],58:["VE"],60:["MY"],61:["AU","CC","CX"],62:["ID"],63:["PH"],64:["NZ"],65:["SG"],66:["TH"],81:["JP"],82:["KR"],84:["VN"],
43740		86:["CN"],90:["TR"],91:["IN"],92:["PK"],93:["AF"],94:["LK"],95:["MM"],98:["IR"],211:["SS"],212:["MA","EH"],213:["DZ"],216:["TN"],218:["LY"],220:["GM"],221:["SN"],222:["MR"],223:["ML"],224:["GN"],225:["CI"],226:["BF"],227:["NE"],228:["TG"],229:["BJ"],230:["MU"],231:["LR"],232:["SL"],233:["GH"],234:["NG"],235:["TD"],236:["CF"],237:["CM"],238:["CV"],239:["ST"],240:["GQ"],241:["GA"],242:["CG"],243:["CD"],244:["AO"],245:["GW"],246:["IO"],247:["AC"],248:["SC"],249:["SD"],250:["RW"],251:["ET"],252:["SO"],
43741		253:["DJ"],254:["KE"],255:["TZ"],256:["UG"],257:["BI"],258:["MZ"],260:["ZM"],261:["MG"],262:["RE","YT"],263:["ZW"],264:["NA"],265:["MW"],266:["LS"],267:["BW"],268:["SZ"],269:["KM"],290:["SH","TA"],291:["ER"],297:["AW"],298:["FO"],299:["GL"],350:["GI"],351:["PT"],352:["LU"],353:["IE"],354:["IS"],355:["AL"],356:["MT"],357:["CY"],358:["FI","AX"],359:["BG"],370:["LT"],371:["LV"],372:["EE"],373:["MD"],374:["AM"],375:["BY"],376:["AD"],377:["MC"],378:["SM"],380:["UA"],381:["RS"],382:["ME"],385:["HR"],386:["SI"],
43742		387:["BA"],389:["MK"],420:["CZ"],421:["SK"],423:["LI"],500:["FK"],501:["BZ"],502:["GT"],503:["SV"],504:["HN"],505:["NI"],506:["CR"],507:["PA"],508:["PM"],509:["HT"],590:["GP","BL","MF"],591:["BO"],592:["GY"],593:["EC"],594:["GF"],595:["PY"],596:["MQ"],597:["SR"],598:["UY"],599:["CW","BQ"],670:["TL"],672:["NF"],673:["BN"],674:["NR"],675:["PG"],676:["TO"],677:["SB"],678:["VU"],679:["FJ"],680:["PW"],681:["WF"],682:["CK"],683:["NU"],685:["WS"],686:["KI"],687:["NC"],688:["TV"],689:["PF"],690:["TK"],691:["FM"],
43743		692:["MH"],800:["001"],808:["001"],850:["KP"],852:["HK"],853:["MO"],855:["KH"],856:["LA"],870:["001"],878:["001"],880:["BD"],881:["001"],882:["001"],883:["001"],886:["TW"],888:["001"],960:["MV"],961:["LB"],962:["JO"],963:["SY"],964:["IQ"],965:["KW"],966:["SA"],967:["YE"],968:["OM"],970:["PS"],971:["AE"],972:["IL"],973:["BH"],974:["QA"],975:["BT"],976:["MN"],977:["NP"],979:["001"],992:["TJ"],993:["TM"],994:["AZ"],995:["GE"],996:["KG"],998:["UZ"]},xa={AC:[,[,,"[46]\\d{4}|[01589]\\d{5}",,,,,,,[5,6]],
43744			[,,"6[2-467]\\d{3}",,,,"62889",,,[5]],[,,"4\\d{4}",,,,"40123",,,[5]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AC",247,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"[01589]\\d{5}",,,,"542011",,,[6]],,,[,,,,,,,,,[-1]]],AD:[,[,,"[16]\\d{5,8}|[37-9]\\d{5}",,,,,,,[6,8,9]],[,,"[78]\\d{5}",,,,"712345",,,[6]],[,,"(?:3\\d|6(?:[0-8]|90\\d{2}))\\d{4}",,,,"312345",,,[6,9]],[,,"180[02]\\d{4}",,,,"18001234",,,[8]],[,,"[19]\\d{5}",,,,"912345",,,[6]],[,,,,,,,,,[-1]],
43745			[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AD",376,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1 $2",["[137-9]|6[0-8]"]],[,"(\\d{4})(\\d{4})","$1 $2",["180","180[02]"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["690"]]],,[,,,,,,,,,[-1]],,,[,,"1800\\d{4}",,,,"18000000",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AE:[,[,,"[2-79]\\d{7,8}|800\\d{2,9}",,,,,,,[5,6,7,8,9,10,11,12]],[,,"[2-4679][2-8]\\d{6}",,,,"22345678",,,[8],[7]],[,,"5[024-68]\\d{7}",,,,"501234567",,,[9]],[,,"400\\d{6}|800\\d{2,9}",,,,"800123456"],[,,"900[02]\\d{5}",
43746			,,,"900234567",,,[9]],[,,"700[05]\\d{5}",,,,"700012345",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AE",971,"00","0",,,"0",,,,[[,"([2-4679])(\\d{3})(\\d{4}
43746)","$1 $2 $3",["[2-4679][2-8]"],"0$1"],[,"(5\\d)(\\d{3})(\\d{4})","$1 $2 $3",["5"],"0$1"],[,"([479]00)(\\d)(\\d{5})","$1 $2 $3",["[479]0"],"$1"],[,"([68]00)(\\d{2,9})","$1 $2",["60|8"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"600[25]\\d{5}",,,,"600212345",,,[9]],,,[,,,,,,,,,[-1]]],AF:[,[,,"[2-7]\\d{8}",,,,,,,[9],[7]],[,,"(?:[25][0-8]|[34][0-4]|6[0-5])[2-9]\\d{6}",
43747			,,,"234567890",,,,[7]],[,,"7(?:[014-9]\\d|2[89]|30)\\d{6}",,,,"701234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AF",93,"00","0",,,"0",,,,[[,"([2-7]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[2-7]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AG:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"268(?:4(?:6[0-38]|84)|56[0-2])\\d{4}",,,,"2684601234",,,,[7]],[,,"268(?:464|7(?:1[3-9]|2\\d|3[246]|64|7[0-689]|8[02-68]))\\d{4}",,,,"2684641234",,
43748			,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,"26848[01]\\d{4}",,,,"2684801234",,,,[7]],"AG",1,"011","1",,,"1",,,,,,[,,"26840[69]\\d{4}",,,,"2684061234",,,,[7]],,"268",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AI:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"2644(?:6[12]|9[78])\\d{4}",,,,"2644612345",,,,[7]],[,,"264(?:235|476|5(?:3[6-9]|8[1-4])|7(?:29|72))\\d{4}",
43749			,,,"2642351234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"AI",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"264",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AL:[,[,,"[2-57]\\d{7}|6\\d{8}|8\\d{5,7}|9\\d{5}",,,,,,,[6,7,8,9],[5]],[,,"(?:2(?:1(?:0[2-9]|[1-9]\\d)|[247]\\d{2}|[35][2-9]\\d|[68](?:0[2-9]|[1-9]\\d)|9(?:[089][2-9]|[1-7]\\d))|3(?:1(?:[04-9][2-9]|[1-3]\\d)|[2-6]\\d{2}|[79](?:[09][2-9]|[1-8]\\d)|8(?:0[2-9]|[1-9]\\d))|4\\d{3}|5(?:1(?:[05-9][2-9]|[1-4]\\d)|[2-578]\\d{2}|6(?:[06-9][2-9]|[1-5]\\d)|9(?:[089][2-9]|[1-7]\\d))|8(?:[19](?:[06-9][2-9]|[1-5]\\d)|[2-6]\\d{2}|[78](?:[089][2-9]|[1-7]\\d)))\\d{4}",
43750			,,,"22345678",,,[8],[5,6,7]],[,,"6(?:[689][2-9]|7[2-6])\\d{6}",,,,"662123456",,,[9]],[,,"800\\d{4}",,,,"8001234",,,[7]],[,,"900[1-9]\\d{2}",,,,"900123",,,[6]],[,,"808[1-9]\\d{2}",,,,"808123",,,[6]],[,,"700[2-9]\\d{4}",,,,"70021234",,,[8]],[,,,,,,,,,[-1]],"AL",355,"00","0",,,"0",,,,[[,"(4)(\\d{3})(\\d{4})","$1 $2 $3",["4[0-6]"],"0$1"],[,"(6\\d)(\\d{3})(\\d{4})","$1 $2 $3",["6"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2358][2-5]|4[7-9]"],"0$1"],[,"(\\d{3})(\\d{3,5})","$1 $2",["[235][16-9]|8[016-9]|[79]"],
43751			"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AM:[,[,,"[1-9]\\d{7}",,,,,,,[8],[5,6]],[,,"(?:1[0-2]\\d|2(?:2[2-46]|3[1-8]|4[2-69]|5[2-7]|6[1-9]|8[1-7])|3[12]2|47\\d)\\d{5}",,,,"10123456",,,,[5,6]],[,,"(?:4[1349]|55|77|88|9[1-9])\\d{6}",,,,"77123456"],[,,"800\\d{5}",,,,"80012345"],[,,"90[016]\\d{5}",,,,"90012345"],[,,"80[1-4]\\d{5}",,,,"80112345"],[,,,,,,,,,[-1]],[,,"60(?:2[078]|[3-7]\\d|8[0-5])\\d{4}",,,,"60271234"],"AM",374,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",
43752			["1|47"],"(0$1)"],[,"(\\d{2})(\\d{6})","$1 $2",["4[1349]|[5-7]|88|9[1-9]"],"0$1"],[,"(\\d{3})(\\d{5})","$1 $2",["[23]"],"(0$1)"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["8|90"],"0 $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AO:[,[,,"[29]\\d{8}",,,,,,,[9]],[,,"2\\d(?:[26-9]\\d|\\d[26-9])\\d{5}",,,,"222123456"],[,,"9[1-49]\\d{7}",,,,"923123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AO",244,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})",
43753			"$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AR:[,[,,"11\\d{8}|[2368]\\d{9}|9\\d{10}",,,,,,,[10,11],[6,7,8]],[,,"11\\d{8}|(?:2(?:2(?:[013]\\d|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[067]\\d)|4(?:7[3-8]|9\\d)|6(?:[01346]\\d|2[24-6]|5[15-8])|80\\d|9(?:[0124789]\\d|3[1-6]|5[234]|6[2-46]))|3(?:3(?:2[79]|6\\d|8[2578])|4(?:[78]\\d|0[0124-9]|[1-35]\\d|4[24-7]|6[02-9]|9[123678])|5(?:[138]\\d|2[1245]|4[1-9]|6[2-4]|7[1-6])|6[24]\\d|7(?:[
vendor: 23,597 bytes, lines 43753-43795
437530469]\\d|1[1568]|2[013-9]|3[145]|5[14-8]|7[2-57]|8[0-24-9])|8(?:[013578]\\d|2[15-7]|4[13-6]|6[1-357-9]|9[124]))|670\\d)\\d{6}",
43754			,,,"1123456789",,,[10],[6,7,8]],[,,"675\\d{7}|9(?:11[2-9]\\d{7}|(?:2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[12358]|5[138]|6[24]|7[069]|8[013578]))[2-9]\\d{6}|\\d{4}[2-9]\\d{5})",,,,"91123456789",,,,[6,7,8]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"60[04579]\\d{7}",,,,"6001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AR",54,"00","0",,,"0?(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:02?|1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[67])|4(?:7[3-578]|9)|6(?:[0136]|2[24-6]|4[6-8]?|5[15-8])|80|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[02568]?|5[2-4]|6[2-46]|72?|8[23]?))|3(?:3(?:2[79]|6|8[2578])|4(?:0[0-24-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6[02-9]|7[126]|8[2379]?|9[1-36-8])|5(?:1|2[1245]|3[237]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|6[24]|7(?:[069]|1[1568]|2[15]|3[145]|4[13]|5[14-8]|7[2-57]|8[126])|8(?:[01]|2[15-7]|3[2578]?|4[13-6]|5[4-8]?|6[1-357-9]|7[36-8]?|8[5-8]?|9[124])))?15)?",
43755			"9$1",,,[[,"([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[68]"],"0$1"],[,"(\\d{2})(\\d{4})","$1-$2",["[2-9]"],"$1"],[,"(\\d{3})(\\d{4})","$1-$2",["[2-9]"],"$1"],[,"(\\d{4})(\\d{4})","$1-$2",["[2-9]"],"$1"],[,"(9)(11)(\\d{4})(\\d{4})","$2 15-$3-$4",["911"],"0$1"],[,"(9)(\\d{3})(\\d{3})(\\d{4})","$2 15-$3-$4",["9(?:2[234689]|3[3-8])","9(?:2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578]))","9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))",
43756				"9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))"],"0$1"],[,"(9)(\\d{4})(\\d{2})(\\d{4})","$2 15-$3-$4",["9[23]"],"0$1"],[,"(11)(\\d{4})(\\d{4})","$1 $2-$3",["1"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3",["2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578])","2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))",
43757				"2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))"],"0$1",,1],[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3",["[23]"],"0$1",,1],[,"(\\d{3})","$1",["1[012]|911"],"$1"]],[[,"([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[68]"],"0$1"],[,"(9)(11)(\\d{4})(\\d{4})","$1 $2 $3-$4",["911"]],[,"(9)(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3-$4",["9(?:2[234689]|3[3-8])","9(?:2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578]))",
43758				"9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))","9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))"]],[,"(9)(\\d{4})(\\d{2})(\\d{4})","$1 $2 $3-$4",["9[23]"]],[,"(11)(\\d{4})(\\d{4})","$1 $2-$3",["1"],"0$1",
43759				,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3",["2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578])","2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))","2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))"],
43760				"0$1",,1],[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3",["[23]"],"0$1",,1]],[,,,,,,,,,[-1]],,,[,,"810\\d{7}",,,,"8101234567",,,[10]],[,,"810\\d{7}",,,,"8101234567",,,[10]],,,[,,,,,,,,,[-1]]],AS:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"6846(?:22|33|44|55|77|88|9[19])\\d{4}",,,,"6846221234",,,,[7]],[,,"684(?:2(?:5[2468]|72)|7(?:3[13]|70))\\d{4}",,,,"6847331234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",
43761			,,,"5002345678"],[,,,,,,,,,[-1]],"AS",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"684",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AT:[,[,,"[1-9]\\d{3,12}",,,,,,,[4,5,6,7,8,9,10,11,12,13],[3]],[,,"1\\d{3,12}|(?:2(?:1[467]|2[13-8]|5[2357]|6[1-46-8]|7[1-8]|8[124-7]|9[1458])|3(?:1[1-8]|3[23568]|4[5-7]|5[1378]|6[1-38]|8[3-68])|4(?:2[1-8]|35|63|7[1368]|8[2457])|5(?:12|2[1-8]|3[357]|4[147]|5[12578]|6[37])|6(?:13|2[1-47]|4[1-35-8]|5[468]|62)|7(?:2[1-8]|3[25]|4[13478]|5[68]|6[16-8]|7[1-6]|9[45]))\\d{3,10}",
43762			,,,"1234567890",,,,[3]],[,,"6(?:5[0-3579]|6[013-9]|[7-9]\\d)\\d{4,10}",,,,"664123456",,,[7,8,9,10,11,12,13]],[,,"800\\d{6,10}",,,,"800123456",,,[9,10,11,12,13]],[,,"9(?:0[01]|3[019])\\d{6,10}",,,,"900123456",,,[9,10,11,12,13]],[,,"8(?:10\\d|2(?:[01]\\d|8\\d?))\\d{5,9}",,,,"810123456",,,[8,9,10,11,12,13]],[,,,,,,,,,[-1]],[,,"780\\d{6,10}",,,,"780123456",,,[9,10,11,12,13]],"AT",43,"00","0",,,"0",,,,[[,"(116\\d{3})","$1",["116"],"$1"],[,"(1)(\\d{3,12})","$1 $2",["1"],"0$1"],[,"(5\\d)(\\d{3,5})","$1 $2",
43763			["5[079]"],"0$1"],[,"(5\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["5[079]"],"0$1"],[,"(5\\d)(\\d{4})(\\d{4,7})","$1 $2 $3",["5[079]"],"0$1"],[,"(\\d{3})(\\d{3,10})","$1 $2",["316|46|51|732|6(?:5[0-3579]|[6-9])|7(?:[28]0)|[89]"],"0$1"],[,"(\\d{4})(\\d{3,9})","$1 $2",["2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[5-79])"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"5(?:(?:0[1-9]|17)\\d{2,10}|[79]\\d{3,11})|720\\d{6,10}",,,,"50123",,,[5,6,7,8,9,10,11,12,13]],,,[,,,,
43764			,,,,,[-1]]],AU:[,[,,"1\\d{4,9}|[2-578]\\d{8}",,,,,,,[5,6,7,8,9,10]],[,,"[237]\\d{8}|8(?:[6-8]\\d{3}|9(?:[02-9]\\d{2}|1(?:[0-57-9]\\d|6[0135-9])))\\d{4}",,,,"212345678",,,[9],[8]],[,,"14(?:5\\d|71)\\d{5}|4(?:[0-3]\\d|4[47-9]|5[0-25-9]|6[6-9]|7[02-9]|8[147-9]|9[017-9])\\d{6}",,,,"412345678",,,[9]],[,,"180(?:0\\d{3}|2)\\d{3}",,,,"1800123456",,,[7,10]],[,,"19(?:0[0126]\\d|[679])\\d{5}",,,,"1900123456",,,[8,10]],[,,"13(?:00\\d{3}|45[0-4]|\\d)\\d{3}",,,,"1300123456",,,[6,8,10]],[,,"500\\d{6}",,,,"500123456",
43765			,,[9]],[,,"550\\d{6}",,,,"550123456",,,[9]],"AU",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88)0011)|001[14-689]","0",,,"0",,"0011",,[[,"([2378])(\\d{4})(\\d{4})","$1 $2 $3",["[2378]"],"(0$1)"],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[45]|14"],"0$1"],[,"(16)(\\d{3,4})","$1 $2",["16"],"0$1"],[,"(16)(\\d{3})(\\d{2,4})","$1 $2 $3",["16"],"0$1"],[,"(1[389]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["1(?:[38]0|90)","1(?:[38]00|90)"],"$1"],[,"(180)(2\\d{3})","$1 $2",["180","1802"],"$1"],[,"(19\\d)(\\d{3})","$1 $2",
43766			["19[13]"],"$1"],[,"(19\\d{2})(\\d{4})","$1 $2",["19[679]"],"$1"],[,"(13)(\\d{2})(\\d{2})","$1 $2 $3",["13[1-9]"],"$1"]],,[,,"16\\d{3,7}",,,,"1612345",,,[5,6,7,8,9]],1,,[,,"1(?:3(?:00\\d{3}|45[0-4]|\\d)\\d{3}|80(?:0\\d{6}|2\\d{3}))",,,,"1300123456",,,[6,7,8,10]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AW:[,[,,"[25-9]\\d{6}",,,,,,,[7]],[,,"5(?:2\\d|8[1-9])\\d{4}",,,,"5212345"],[,,"(?:5(?:6\\d|9[2-478])|6(?:[039]0|22|4[01]|6[0-2])|7[34]\\d|9(?:6[45]|9[4-8]))\\d{4}",,,,"5601234"],[,,"800\\d{4}",,,,"8001234"],
43767			[,,"900\\d{4}",,,,"9001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"28\\d{5}|501\\d{4}",,,,"5011234"],"AW",297,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AX:[,[,,"[15]\\d{6,9}|2\\d{4,9}|3\\d{5,9}|4\\d{7,10}|[67]\\d{7,9}|8\\d{7,8}",,,,,,,[5,6,7,8,9,10,11]],[,,"18[1-8]\\d{4,6}",,,,"181234567",,,[7,8,9]],[,,"4(?:[0-8]\\d{6,8}|9\\d{9})|50\\d{6,8}",,,,"412345678",,,[8,9,10,11]],[,,"800\\d{5,6}",,,,"800123456",,,[8,9]],[,,"[67]00\\d{5,6}",
43768			,,,"600123456",,,[8,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AX",358,"00|99(?:[02469]|5(?:11|33|5[59]|88|9[09]))","0",,,"0",,"00",,,,[,,,,,,,,,[-1]],,,[,,"100\\d{4,6}|20(?:0\\d{4,6}|2[023]\\d{4,5}|9[89]\\d{1,6})|300\\d{3,7}|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",,,,"1001234",,,[5,6,7,8,9,10]],[,,"10(?:0\\d{4,6}|[1-9]\\d{5,7})|2(?:0(?:0\\d{4,6}|[13-8]\\d{5,7}|2(?:[023]\\d{4,5}|[14-9]\\d{4,6})|9(?:[0-7]\\d{4,6}|[89]\\d{1,6}))|9\\d{5,8})|3(?:0(?:0\\d{3,7}|[1-57-9]\\d{5,7}|6(?:\\d{3}|\\d{5,7}))|93\\d{5,7})|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",
43769			,,,"10112345",,,[5,6,7,8,9,10]],,,[,,,,,,,,,[-1]]],AZ:[,[,,"[1-9]\\d{8}",,,,,,,[9],[7]],[,,"(?:1[28]\\d{3}|2(?:02|1[24]|2[2-4]|33|[45]2|6[23])\\d{2}|365(?:[0-46-9]\\d|5[0-35-9]))\\d{4}",,,,"123123456",,,,[7]],[,,"(?:36554|(?:4[04]|5[015]|60|7[07])\\d{3})\\d{4}",,,,"401234567"],[,,"88\\d{7}",,,,"881234567"],[,,"900200\\d{3}",,,,"900200123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AZ",994,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["(?:1[28]|2(?:[45]2|[0-36])|365)"],
43770			"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[4-8]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["9"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BA:[,[,,"[3-9]\\d{7,8}",,,,,,,[8,9],[6]],[,,"(?:[35]\\d|49)\\d{6}",,,,"30123456",,,[8],[6]],[,,"6(?:0(?:3\\d|40)|[1-356]\\d|44[0-6]|71[137])\\d{5}",,,,"61123456"],[,,"8[08]\\d{6}",,,,"80123456",,,[8]],[,,"9[0246]\\d{6}",,,,"90123456",,,[8]],[,,"8[12]\\d{6}",,,,"82123456",,,[8]],[,,,,,,,,,
43771			[-1]],[,,,,,,,,,[-1]],"BA",387,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2-$3",["[3-5]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["6[1-356]|[7-9]"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4",["6[047]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"70[23]\\d{5}",,,,"70223456",,,[8]],,,[,,,,,,,,,[-1]]],BB:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"246(?:2(?:2[78]|7[0-4])|4(?:1[024-6]|2\\d|3[2-9])|5(?:20|[34]\\d|54|7[1-3])|6(?:2\\d|38)|7(?:37|57)|9(?:1[89]|63))\\d{4}",
43772			,,,"2464123456",,,,[7]],[,,"246(?:2(?:[356]\\d|4[0-57-9]|8[0-79])|45\\d|8(?:[2-5]\\d|83))\\d{4}",,,,"2462501234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900\\d{7}|246976\\d{4}",,,,"9002123456",,,,[7]],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,"24631\\d{5}",,,,"2463101234",,,,[7]],"BB",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"246",[,,,,,,,,,[-1]],[,,"246(?:292|367|4(?:1[7-9]|3[01]|44|67)|736)\\d{4}",,,,"2464301234",,,,[7]],,,[,,,,,
43773			,,,,[-1]]],BD:[,[,,"[2-79]\\d{5,9}|1\\d{9}|8[0-7]\\d{4,8}",,,,,,,[6,7,8,9,10]],[,,"2(?:[45]\\d{3}|7(?:1[0-267]|2[0-289]|3[0-29]|4[01]|5[1-3]|6[013]|7[0178]|91)|8(?:0[125]|[139][1-6]|2[0157-9]|41|6[1-35]|7[1-5]|8[1-8]|90)|9(?:0[0-2]|1[0-4]|2[568]|3[3-6]|5[5-7]|6[0167]|7[15]|8[0146-9]))\\d{4}|3(?:12?[5-7]\\d{2}|0(?:2(?:[025-79]\\d|[348]\\d{1,2})|3(?:[2-4]\\d|[56]\\d?))|2(?:1\\d{2}|2(?:[12]\\d|[35]\\d{1,2}|4\\d?))|3(?:1\\d{2}|2(?:[2356]\\d|4\\d{1,2}))|4(?:1\\d{2}|2(?:2\\d{1,2}|[47]|5\\d{2}))|5(?:1\\d{2}|29)|[67]1\\d{2}|8(?:1\\d{2}|2(?:2\\d{2}|3|4\\d)))\\d{3}|4(?:0(?:2(?:[09]\\d|7)|33\\d{2})|1\\d{3}|2(?:1\\d{2}|2(?:[25]\\d?|[348]\\d|[67]\\d{1,2}))|3(?:1\\d{2}(?:\\d{2})?|2(?:[045]\\d|[236-9]\\d{1,2})|32\\d{2})|4(?:[18]\\d{2}|2(?:[2-46]\\d{2}|3)|5[25]\\d{2})|5(?:1\\d{2}|2(?:3\\d|5))|6(?:[18]\\d{2}|2(?:3(?:\\d{2})?|[46]\\d{1,2}|5\\d{2}|7\\d)|5(?:3\\d?|4\\d|[57]\\d{1,2}|6\\d{2}|8))|71\\d{2}|8(?:[18]\\d{2}|23\\d{2}|54\\d{2})|9(?:[18]\\d{2}|2[2-5]\\d{2}|53\\d{1,2}))\\d{3}|5(?:02[03489]\\d{2}|1\\d{2}|2(?:1\\d{2}|2(?:2(?:\\d{2})?|[457]\\d{2}))|3(?:1\\d{2}|2(?:[37](?:\\d{2})?|[569]\\d{2}))|4(?:1\\d{2}|2[46]\\d{2})|5(?:1\\d{2}|26\\d{1,2})|6(?:[18]\\d{2}|2|53\\d{2})|7(?:1|24)\\d{2}|8(?:1|26)\\d{2}|91\\d{2})\\d{3}|6(?:0(?:1\\d{2}|2(?:3\\d{2}|4\\d{1,2}))|2(?:2[2-5]\\d{2}|5(?:[3-5]\\d{2}|7)|8\\d{2})|3(?:1|2[3478])\\d{2}|4(?:1|2[34])\\d{2}|5(?:1|2[47])\\d{2}|6(?:[18]\\d{2}|6(?:2(?:2\\d|[34]\\d{2})|5(?:[24]\\d{2}|3\\d|5\\d{1,2})))|72[2-5]\\d{2}|8(?:1\\d{2}|2[2-5]\\d{2})|9(?:1\\d{2}|2[2-6]\\d{2}))\\d{3}|7(?:(?:02|[3-589]1|6[12]|72[24])\\d{2}|21\\d{3}|32)\\d{3}|8(?:(?:4[12]|[5-7]2|1\\d?)|(?:0|3[12]|[5-7]1|217)\\d)\\d{4}|9(?:[35]1|(?:[024]2|81)\\d|(?:1|[24]1)\\d{2})\\d{3}",
43774			,,,"27111234",,,[6,7,8,9]],[,,"(?:1[13-9]\\d|(?:3[78]|44)[02-9]|6(?:44|6[02-9]))\\d{7}",,,,"1812345678",,,[10]],[,,"80[03]\\d{7}",,,,"8001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"96(?:0[49]|1[0-4]|6[69])\\d{6}",,,,"9604123456",,,[10]],"BD",880,"00","0",,,"0",,,,[[,"(2)(\\d{7,8})","$1-$2",["2"],"0$1"],[,"(\\d{2})(\\d{4,6})","$1-$2",["[3-79]1"],"0$1"],[,"(\\d{4})(\\d{3,6})","$1-$2",["1|3(?:0|[2-58]2)|4(?:0|[25]2|3[23]|[4689][25])|5(?:[02-578]2|6[25])|6(?:[0347-9]2|[26][25])|7[02-9]2|8(?:[023][23]|[4-7]2)|9(?:[02][23]|[458]2|6[016])"],
43775			"0$1"],[,"(\\d{3})(\\d{3,7})","$1-$2",["[3-79][2-9]|8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BE:[,[,,"[1-9]\\d{7,8}",,,,,,,[8,9]],[,,"(?:1[0-69]|[23][2-8]|4[23]|5\\d|6[013-57-9]|71|8[1-79]|9[2-4])\\d{6}|80[2-8]\\d{5}",,,,"12345678",,,[8]],[,,"4(?:6[0135-8]|[79]\\d|8[3-9])\\d{6}",,,,"470123456",,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"(?:70[2-467]|90[0-79])\\d{5}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BE",32,"00","0",,,
43776			"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["4[6-9]"],"0$1"],[,"(\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[23]|4[23]|9[2-4]"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[156]|7[018]|8(?:0[1-9]|[1-79])"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["(?:80|9)0"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"78\\d{6}",,,,"78123456",,,[8]],,,[,,,,,,,,,[-1]]],BF:[,[,,"[25-7]\\d{7}",,,,,,,[8]],[,,"2(?:0(?:49|5[23]|6[56]|9[016-9])|4(?:4[569]|5[4-6]|6[56]|7[0179])|5(?:[34]\\d|50|6[5-7]))\\d{4}",
43777			,,,"20491234"],[,,"(?:5[15-8]|[67]\\d)\\d{6}",,,,"70123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BF",226,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BG:[,[,,"[23567]\\d{5,7}|[489]\\d{6,8}",,,,,,,[6,7,8,9],[4,5]],[,,"2\\d{5,7}|(?:[36]\\d|5[1-9]|8[1-6]|9[1-7])\\d{5,6}|(?:4(?:[124-7]\\d|3[1-6])|7(?:0[1-9]|[1-9]\\d))\\d{4,5}",,,,"2123456",,,[6,7,8],[4,5]],[,,"(?:8[7-9]\\d|9(?:8\\d|9[69]))\\d{6}|4(?:3[0789]|8\\d)\\d{5}",
43778			,,,"48123456",,,[8,9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"90\\d{6}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,"700\\d{5}",,,,"70012345",,,[8]],[,,,,,,,,,[-1]],"BG",359,"00","0",,,"0",,,,[[,"(2)(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4",["2"],"0$1"],[,"(2)(\\d{3})(\\d{3,4})","$1 $2 $3",["2"],"0$1"],[,"(\\d{3})(\\d{4})","$1 $2",["43[124-7]|70[1-9]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3",["43[124-7]|70[1-9]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["[78]00"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3})",
43779			"$1 $2 $3",["99[69]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3",["[356]|4[124-7]|7[1-9]|8[1-6]|9[1-7]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["48|8[7-9]|9[08]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BH:[,[,,"[136-9]\\d{7}",,,,,,,[8]],[,,"(?:1(?:3[1356]|6[0156]|7\\d)\\d|6(?:1[16]\\d|500|6(?:0\\d|3[12]|44|7[7-9])|9[69][69])|7(?:1(?:11|78)|7\\d{2}))\\d{4}",,,,"17001234"],[,,"(?:3(?:[1-4679]\\d|5[013-69]|8[0-47-9])\\d|6(?:3(?:00|33|6[16])|6(?:[69]\\d|3[03-9]|7[0-6])))\\d{4}",
43780			,,,"36001234"],[,,"80\\d{6}",,,,"80123456"],[,,"(?:87|9[014578])\\d{6}",,,,"90123456"],[,,"84\\d{6}",,,,"84123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BH",973,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BI:[,[,,"[267]\\d{7}",,,,,,,[8]],[,,"22\\d{6}",,,,"22201234"],[,,"(?:29|6[189]|7[124-9])\\d{6}",,,,"79561234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BI",257,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
43781			"$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BJ:[,[,,"[2689]\\d{7}",,,,,,,[8]],[,,"2(?:02|1[037]|2[45]|3[68])\\d{5}",,,,"20211234"],[,,"(?:6[1-8]|9[03-9])\\d{6}",,,,"90011234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"857[58]\\d{4}",,,,"85751234"],"BJ",229,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2689]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"81\\d{6}",,,,"81123456"],,,[,,,,,,,,,[-1]]],BL:[,[,,"[56]\\d{8}",
43782			,,,,,,[9]],[,,"590(?:2[7-9]|5[12]|87)\\d{4}",,,,"590271234"],[,,"690(?:0[05-9]|[1-9]\\d)\\d{4}",,,,"690001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BL",590,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BM:[,[,,"[4589]\\d{9}",,,,,,,[10],[7]],[,,"441(?:2(?:02|23|61|[3479]\\d)|[46]\\d{2}|5(?:4\\d|60|89)|824)\\d{4}",,,,"4412345678",,,,[7]],[,,"441(?:[37]\\d|5[0-39])\\d{5}",,,,"4413701234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",
43783			,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"BM",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"441",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BN:[,[,,"[2-578]\\d{6}",,,,,,,[7]],[,,"2(?:[013-9]\\d|2[0-7])\\d{4}|[3-5]\\d{6}",,,,"2345678"],[,,"22[89]\\d{4}|[78]\\d{6}",,,,"7123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BN",673,"00",,,,,,,,[[,"([2-578]\\d{2})(\\d{4})",
43784			"$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BO:[,[,,"[23467]\\d{7}|8\\d{8}",,,,,,,[8,9],[7]],[,,"(?:2(?:2\\d{2}|5(?:11|[258]\\d|9[67])|6(?:12|2\\d|9[34])|8(?:2[34]|39|62))|3(?:3\\d{2}|4(?:6\\d|8[24])|8(?:25|42|5[257]|86|9[25])|9(?:2\\d|3[234]|4[248]|5[24]|6[2-6]|7\\d))|4(?:4\\d{2}|6(?:11|[24689]\\d|72)))\\d{4}",,,,"22123456",,,[8],[7]],[,,"[67]\\d{7}",,,,"71234567",,,[8]],[,,"80017\\d{4}",,,,"800171234",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,
43785			,,,,,,,[-1]],"BO",591,"00(1\\d)?","0",,,"0(1\\d)?",,,,[[,"([234])(\\d{7})","$1 $2",["[234]"],,"0$CC $1"],[,"([67]\\d{7})","$1",["[67]"],,"0$CC $1"],[,"(800)(\\d{2})(\\d{4})","$1 $2 $3",["800"],,"0$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BQ:[,[,,"[347]\\d{6}",,,,,,,[7]],[,,"(?:318[023]|41(?:6[023]|70)|7(?:1[578]|50)\\d)\\d{3}",,,,"7151234"],[,,"(?:31(?:8[14-8]|9[14578])|416[145-9]|7(?:0[01]|7[07]|8\\d|9[056])\\d)\\d{3}",,,,"3181234"],[,,,,,,,,,[-1]],[,,,,,,,,
43786			,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BQ",599,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BR:[,[,,"[1-46-9]\\d{7,10}|5(?:[0-4]\\d{7,9}|5(?:[2-8]\\d{7}|9\\d{7,8}))",,,,,,,[8,9,10,11]],[,,"(?:[14689][1-9]|2[12478]|3[1-578]|5[13-5]|7[13-579])[2-5]\\d{7}",,,,"1123456789",,,[10],[8]],[,,"(?:[189][1-9]|2[12478])(?:7|9\\d)\\d{7}|(?:3[1-578]|[46][1-9]|5[13-5]|7[13-579])(?:[6-8]|9\\d?)\\d{7}",,,,"11961234567",,,[10,11],[8]],[,,"800\\d{6,7}",,,,"800123456",
43787			,,[9,10]],[,,"(?:300|[59]00\\d?)\\d{6}",,,,"300123456",,,[9,10]],[,,"(?:300\\d(?:\\d{2})?|40(?:0\\d|20))\\d{4}",,,,"40041234",,,[8,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BR",55,"00(?:1[245]|2[1-35]|31|4[13]|[56]5|99)","0",,,"0(?:(1[245]|2[1-35]|31|4[13]|[56]5|99)(\\d{10,11}))?","$2",,,[[,"(\\d{4})(\\d{4})","$1-$2",["(?:300|40[02])","(?:300|40(?:0|20))"]],[,"([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3",["[3589]00"],"0$1"],[,"(\\d{3,5})","$1",["1[125689]"],"$1"],[,"(\\d{4})(\\d{4})","$1-$2",["[2-9](?:[1-9]|0[1-9])"],
43788			"$1"],[,"(\\d{5})(\\d{4})","$1-$2",["9(?:[1-9]|0[1-9])"],"$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3",["[1-9][1-9]"],"($1)","0 $CC ($1)"],[,"(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3",["[1-9][1-9]9"],"($1)","0 $CC ($1)"]],[[,"(\\d{4})(\\d{4})","$1-$2",["(?:300|40[02])","(?:300|40(?:0|20))"]],[,"([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3",["[3589]00"],"0$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3",["[1-9][1-9]"],"($1)","0 $CC ($1)"],[,"(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3",["[1-9][1-9]9"],"($1)","0 $CC ($1)"]],
43789			[,,,,,,,,,[-1]],,,[,,"(?:300\\d|40(?:0\\d|20))\\d{4}",,,,"40041234",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BS:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"242(?:3(?:02|[236][1-9]|4[0-24-9]|5[0-68]|7[3467]|8[0-4]|9[2-467])|461|502|6(?:0[1-3]|12|7[67]|8[78]|9[89])|7(?:02|88))\\d{4}",,,,"2423456789",,,,[7]],[,,"242(?:3(?:5[79]|[79]5)|4(?:[2-4][1-9]|5[1-8]|6[2-8]|7\\d|81)|5(?:2[45]|3[35]|44|5[1-9]|65|77)|6[34]6|7(?:27|38)|8(?:0[1-9]|1[02-9]|2\\d|99))\\d{4}",,,,"2423591234",,,,[7]],[,,"242300\\d{4}|8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",
43790			,,,"8002123456",,,,[7]],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"BS",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"242",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BT:[,[,,"[1-8]\\d{6,7}",,,,,,,[7,8],[6]],[,,"(?:2[3-6]|[34][5-7]|5[236]|6[2-46]|7[246]|8[2-4])\\d{5}",,,,"2345678",,,[7],[6]],[,,"(?:1[67]|77)\\d{6}",,,,"17123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
43791			"BT",975,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["1|77"]],[,"([2-8])(\\d{3})(\\d{3})","$1 $2 $3",["[2-68]|7[246]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BW:[,[,,"[2-79]\\d{6,7}",,,,,,,[7,8]],[,,"(?:2(?:4[0-48]|6[0-24]|9[0578])|3(?:1[0-35-9]|55|[69]\\d|7[01])|4(?:6[03]|7[1267]|9[0-5])|5(?:3[0389]|4[0489]|7[1-47]|88|9[0-49])|6(?:2[1-35]|5[149]|8[067]))\\d{4}",,,,"2401234",,,[7]],[,,"7(?:[1-6]\\d|7[014-8])\\d{5}",,,,"71123456",,,[8]],[,,,,,,
43792			,,,[-1]],[,,"90\\d{5}",,,,"9012345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"79[12][01]\\d{4}",,,,"79101234",,,[8]],"BW",267,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[2-6]"]],[,"(7\\d)(\\d{3})(\\d{3})","$1 $2 $3",["7"]],[,"(90)(\\d{5})","$1 $2",["9"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BY:[,[,,"[1-4]\\d{8}|800\\d{3,7}|[89]\\d{9,10}",,,,,,,[6,7,8,9,10,11],[5]],[,,"(?:1(?:5(?:1[1-5]|[24]\\d|6[2-4]|9[1-7])|6(?:[235]\\d|4[1-7])|7\\d{2})|2(?:1(?:[246]\\d|3[0-35-9]|5[1-9])|2(?:[235]\\d|4[0-8])|3(?:[26]\\d|3[02-79]|4[024-7]|5[03-7])))\\d{5}",
43793			,,,"152450911",,,[9],[5,6,7]],[,,"(?:2(?:5[5679]|9[1-9])|33\\d|44\\d)\\d{6}",,,,"294911911",,,[9]],[,,"8(?:0[13]|20\\d)\\d{7}|800\\d{3,7}",,,,"8011234567"],[,,"(?:810|902)\\d{7}",,,,"9021234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"249\\d{6}",,,,"249123456",,,[9]],"BY",375,"810","8",,,"8?0?",,"8~10",,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4",["17[0-3589]|2[4-9]|[34]","17(?:[02358]|1[0-2]|9[0189])|2[4-9]|[34]"],"8 0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2-$3-$4",["1(?:5[24]|6[235]|7[467])|2(?:1[246]|2[25]|3[26])",
43794			"1(?:5[24]|6(?:2|3[04-9]|5[0346-9])|7(?:[46]|7[37-9]))|2(?:1[246]|2[25]|3[26])"],"8 0$1"],[,"(\\d{4})(\\d{2})(\\d{3})","$1 $2-$3",["1(?:5[169]|6[3-5]|7[179])|2(?:1[35]|2[34]|3[3-5])","1(?:5[169]|6(?:3[1-3]|4|5[125])|7(?:1[3-9]|7[0-24-6]|9[2-7]))|2(?:1[35]|2[34]|3[3-5])"],"8 0$1"],[,"([89]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["8[01]|9"],"8 $1"],[,"(82\\d)(\\d{4})(\\d{4})","$1 $2 $3",["82"],"8 $1"],[,"(800)(\\d{3})","$1 $2",["800"],"8 $1"],[,"(800)(\\d{2})(\\d{2,4})","$1 $2 $3",["800"],"8 $1"]],,[,,
43795			,,,,,,,[-1]],,,[,,"8(?:0[13]|10|20\\d)\\d{7}|800\\d{3,7}|902\\d{7}",,,,"82012345678"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BZ:[,[,,"[2-8]\\d{6}|0\\d{10}
vendor: 8,885 bytes, lines 43795-43811
43795",,,,,,,[7,11]],[,,"(?:2(?:[02]\\d|36)|[3-58][02]\\d|7(?:[02]\\d|32))\\d{4}",,,,"2221234",,,[7]],[,,"6[0-35-7]\\d{5}",,,,"6221234",,,[7]],[,,"0800\\d{7}",,,,"08001234123",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BZ",501,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1-$2",["[2-8]"]],[,"(0)(800)(\\d{4})(\\d{3})","$1-$2-$3-$4",["0"]]],
43796			,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CA:[,[,,"[2-9]\\d{9}|3\\d{6}",,,,,,,[7,10]],[,,"(?:2(?:04|[23]6|[48]9|50)|3(?:06|43|65)|4(?:03|1[68]|3[178]|50)|5(?:06|1[49]|48|79|8[17])|6(?:0[04]|13|22|39|47)|7(?:0[59]|78|8[02])|8(?:[06]7|19|25|73)|90[25])[2-9]\\d{6}|310\\d{4}",,,,"2042345678",,,[10],[7]],[,,"(?:2(?:04|[23]6|[48]9|50)|3(?:06|43|65)|4(?:03|1[68]|3[178]|50)|5(?:06|1[49]|48|79|8[17])|6(?:0[04]|13|22|39|47)|7(?:0[59]|78|8[02])|8(?:[06]7|19|25|73)|90[25])[2-9]\\d{6}",
43797			,,,"2042345678",,,[10],[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}|310\\d{4}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456",,,[10]],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678",,,[10]],[,,,,,,,,,[-1]],"CA",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CC:[,[,,"[1458]\\d{5,9}",,,,,,,[6,7,9,10],[8]],[,,"89162\\d{4}",,,,"891621234",,,[9],[8]],[,,"14(?:5\\d|71)\\d{5}|4(?:[0-2]\\d|3[0-57-9]|4[47-9]|5[0-25-9]|6[6-9]|7[02-9]|8[147-9]|9[017-9])\\d{6}",
43798			,,,"412345678",,,[9]],[,,"180(?:0\\d{3}|2)\\d{3}",,,,"1800123456",,,[7,10]],[,,"190[0126]\\d{6}",,,,"1900123456",,,[10]],[,,"13(?:00\\d{2})?\\d{4}",,,,"1300123456",,,[6,10]],[,,"500\\d{6}",,,,"500123456",,,[9]],[,,"550\\d{6}",,,,"550123456",,,[9]],"CC",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88))?001[14-689]","0",,,"0",,"0011",,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CD:[,[,,"[2-6]\\d{6}|[18]\\d{6,8}|9\\d{8}",,,,,,,[7,9]],[,,"1(?:2\\d{7}|\\d{6})|[2-6]\\d{6}",,,,"1234567"],
43799			[,,"8(?:[0-2459]\\d{2}|8)\\d{5}|9[017-9]\\d{7}",,,,"991234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CD",243,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["12"],"0$1"],[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["8[0-2459]|9"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["88"],"0$1"],[,"(\\d{2})(\\d{5})","$1 $2",["[1-6]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CF:[,[,,"[278]\\d{7}",,,,,,,[8]],[,,"2[12]\\d{6}",
43800			,,,"21612345"],[,,"7[0257]\\d{6}",,,,"70012345"],[,,,,,,,,,[-1]],[,,"8776\\d{4}",,,,"87761234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CF",236,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CG:[,[,,"[028]\\d{8}",,,,,,,[9]],[,,"222[1-589]\\d{5}",,,,"222123456"],[,,"0[14-6]\\d{7}",,,,"061234567"],[,,,,,,,,,[-1]],[,,"80(?:0\\d{2}|11[01])\\d{4}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,
43801			[-1]],"CG",242,"00",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["801"]],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[02]"]],[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["800"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CH:[,[,,"[2-9]\\d{8}|860\\d{9}",,,,,,,[9,12]],[,,"(?:2[12467]|3[1-4]|4[134]|5[256]|6[12]|[7-9]1)\\d{7}",,,,"212345678",,,[9]],[,,"7[5-9]\\d{7}",,,,"781234567",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"90[016]\\d{6}",,,,"900123456",,,[9]],[,
43802			,"84[0248]\\d{6}",,,,"840123456",,,[9]],[,,"878\\d{6}",,,,"878123456",,,[9]],[,,,,,,,,,[-1]],"CH",41,"00","0",,,"0",,,,[[,"([2-9]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2-7]|[89]1"],"0$1"],[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["8[047]|90"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["860"],"0$1"]],,[,,"74[0248]\\d{6}",,,,"740123456",,,[9]],,,[,,,,,,,,,[-1]],[,,"5[18]\\d{7}",,,,"581234567",,,[9]],,,[,,"860\\d{9}",,,,"860123456789",,,[12]]],CI:[,[,,"[02-8]\\d{7}",
43803			,,,,,,[8]],[,,"(?:2(?:0[023]|1[02357]|[23][045]|4[03-5])|3(?:0[06]|1[069]|[2-4][07]|5[09]|6[08]))\\d{5}",,,,"21234567"],[,,"(?:0[1-9]|4\\d|5[14-9]|6[015-79]|[78][4-9])\\d{6}",,,,"01234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CI",225,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CK:[,[,,"[2-8]\\d{4}",,,,,,,[5]],[,,"(?:2\\d|3[13-7]|4[1-5])\\d{3}",,,,"21234"],[,,"[5-8]\\d{4}",
43804			,,,"71234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CK",682,"00",,,,,,,,[[,"(\\d{2})(\\d{3})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CL:[,[,,"(?:[2-9]|600|123)\\d{7,8}",,,,,,,[9,10,11],[7,8]],[,,"2(?:1962\\d{4}|2\\d{7}|32[0-467]\\d{5})|(?:3[2-5]|[47][1-35]|5[1-3578]|6[13-57]|9[3-9])\\d{7}",,,,"221234567",,,[9],[7,8]],[,,"2(?:1962\\d{4}|2\\d{7}|32[0-467]\\d{5})|(?:3[2-5]|[47][1-35]|5[1-3578]|6[13-57]|9[3-9])\\d{7}",,
43805			,,"961234567",,,[9],[8]],[,,"800\\d{6}|1230\\d{7}",,,,"800123456",,,[9,11]],[,,,,,,,,,[-1]],[,,"600\\d{7,8}",,,,"6001234567",,,[10,11]],[,,,,,,,,,[-1]],[,,"44\\d{7}",,,,"441234567",,,[9]],"CL",56,"(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0",,,"0|(1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,,1,[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["2[23]"],"($1)","$CC ($1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[357]|4[1-35]|6[13-57]"],"($1)","$CC ($1)"],[,"(9)(\\d{4})(\\d{4})","$1 $2 $3",
43806			["9"],"0$1"],[,"(44)(\\d{3})(\\d{4})","$1 $2 $3",["44"],"0$1"],[,"([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3",["60|8"],"$1"],[,"(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4",["60"],"$1"],[,"(1230)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"$1"],[,"(\\d{5})(\\d{4})","$1 $2",["219"],"($1)","$CC ($1)"],[,"(\\d{4,5})","$1",["[1-9]"],"$1"]],[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["2[23]"],"($1)","$CC ($1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[357]|4[1-35]|6[13-57]"],"($1)","$CC ($1)"],[,"(9)(\\d{4})(\\d{4})",
43807			"$1 $2 $3",["9"],"0$1"],[,"(44)(\\d{3})(\\d{4})","$1 $2 $3",["44"],"0$1"],[,"([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3",["60|8"],"$1"],[,"(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4",["60"],"$1"],[,"(1230)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"$1"],[,"(\\d{5})(\\d{4})","$1 $2",["219"],"($1)","$CC ($1)"]],[,,,,,,,,,[-1]],,,[,,"600\\d{7,8}",,,,"6001234567",,,[10,11]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CM:[,[,,"[2368]\\d{7,8}",,,,,,,[8,9]],[,,"2(?:22|33|4[23])\\d{6}",,,,"222123456",,,[9]],[,,"6[5-9]\\d{7}",
43808			,,,"671234567",,,[9]],[,,"88\\d{6}",,,,"88012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CM",237,"00",,,,,,,,[[,"([26])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["[26]"]],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[23]|88"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CN:[,[,,"[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9\\d{7,10}",,,,,,,[7,8,9,10,11,12],[5,6]],[,,"21(?:100\\d{2}|95\\d{3,4}|\\d{8,10})|(?:10|2[02-57-9]|3(?:11|7[179])|4(?:[15]1|3[1-35])|5(?:1\\d|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98))(?:100\\d{2}|95\\d{3,4}|\\d{8})|(?:3(?:1[02-9]|35|49|5\\d|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|3[3-9]|5[2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[17]\\d|2[248]|3[04-9]|4[3-6]|5[0-4689]|6[2368]|9[02-9])|8(?:078|1[236-8]|2[5-7]|3\\d|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]\\d|4[13]|5[1-5]))(?:100\\d{2}|95\\d{3,4}|\\d{7})|80(?:29|6[03578]|7[018]|81)\\d{4}",
43809			,,,"1012345678",,,,[5,6]],[,,"1(?:[38]\\d|4[57]|5[0-35-9]|7[0-35-8])\\d{8}",,,,"13123456789",,,[11]],[,,"(?:10)?800\\d{7}",,,,"8001234567",,,[10,12]],[,,"16[08]\\d{5}",,,,"16812345",,,[8]],[,,"400\\d{7}|950\\d{7,8}|(?:10|2[0-57-9]|3(?:[157]\\d|35|49|9[1-68])|4(?:[17]\\d|2[179]|[35][1-9]|6[4789]|8[23])|5(?:[1357]\\d|2[37]|4[36]|6[1-46]|80|9[1-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]\\d|2[248]|3[014-9]|4[3-6]|6[023689])|8(?:1[236-8]|2[5-7]|[37]\\d|5[14-9]|8[3678]|9[1-8])|9(?:0[1-3689]|1[1-79]|[379]\\d|4[13]|5[1-5]))96\\d{3,4}",
43810			,,,"4001234567",,,[7,8,9,10,11],[5,6]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CN",86,"(1(?:[129]\\d{3}|79\\d{2}))?00","0",,,"(1(?:[129]\\d{3}|79\\d{2}))|0",,"00",,[[,"(80\\d{2})(\\d{4})","$1 $2",["80[2678]"],"0$1","$CC $1",1],[,"([48]00)(\\d{3})(\\d{4})","$1 $2 $3",["[48]00"]],[,"(\\d{5,6})","$1",["100|95"]],[,"(\\d{2})(\\d{5,6})","$1 $2",["(?:10|2\\d)[19]","(?:10|2\\d)(?:10|9[56])","(?:10|2\\d)(?:100|9[56])"],"0$1","$CC $1"],[,"(\\d{3})(\\d{5,6})","$1 $2",["[3-9]","[3-9]\\d{2}[19]","[3-9]\\d{2}(?:10|9[56])"],
43811			"0$1","$CC $1"],[,"(\\d{3,4})(\\d{4})","$1 $2",["[2-9]"]],[,"(21)(\\d{4})(\\d{4,6})","$1 $2 $3",["21"],"0$1","$CC $1",1],[,"([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["10[1-9]|2[02-9]","10[1-9]|2[02-9]","10(?:[1-79]|8(?:[1-9]|0[1-9]))|2[02-9]"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{3})(\\d{4}
43811)","$1 $2 $3",["3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])"],
43812			"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["3(?:11|7[179])|4(?:[15]1|3[1-35])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98)"],"0$1","$CC $1",1],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["807","8078"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["1[3-578]"],,"$CC $1"],[,"(10800)(\\d{3})(\\d{4})","$1 $2 $3",["108","1080","10800"]],[,"(\\d{3})(\\d{7,8})","$1 $2",["950"]]],[[,"(80\\d{2})(\\d{4})","$1 $2",["80[2678]"],"0$1","$CC $1",1],[,"([48]00)(\\d{3})(\\d{4})",
43813			"$1 $2 $3",["[48]00"]],[,"(\\d{2})(\\d{5,6})","$1 $2",["(?:10|2\\d)[19]","(?:10|2\\d)(?:10|9[56])","(?:10|2\\d)(?:100|9[56])"],"0$1","$CC $1"],[,"(\\d{3})(\\d{5,6})","$1 $2",["[3-9]","[3-9]\\d{2}[19]","[3-9]\\d{2}(?:10|9[56])"],"0$1","$CC $1"],[,"(21)(\\d{4})(\\d{4,6})","$1 $2 $3",["21"],"0$1","$CC $1",1],[,"([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["10[1-9]|2[02-9]","10[1-9]|2[02-9]","10(?:[1-79]|8(?:[1-9]|0[1-9]))|2[02-9]"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])"],
43814			"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["3(?:11|7[179])|4(?:[15]1|3[1-35])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98)"],"0$1","$CC $1",1],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["807","8078"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["1[3-578]"],,"$CC $1"],[,"(10800)(\\d{3})(\\d{4})","$1 $2 $3",["108","1080","10800"]],[,"(\\d{3})(\\d{7,8})","$1 $2",["950"]]],[,,,,,,,,,[-1]],,,[,,"(?:4|(?:10)?8)00\\d{7}|950\\d{7,8}",,,,"4001234567",
43815			,,[10,11,12]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CO:[,[,,"(?:[13]\\d{0,3}|[24-8])\\d{7}",,,,,,,[8,10,11],[7]],[,,"[124-8][2-9]\\d{6}",,,,"12345678",,,[8],[7]],[,,"3(?:0[0-5]|1\\d|2[0-3]|5[01])\\d{7}",,,,"3211234567",,,[10]],[,,"1800\\d{7}",,,,"18001234567",,,[11]],[,,"19(?:0[01]|4[78])\\d{7}",,,,"19001234567",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CO",57,"00(?:4(?:[14]4|56)|[579])","0",,,"0([3579]|4(?:44|56))?",,,,[[,"(\\d)(\\d{7})","$1 $2",["1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","1(?:8[2-9]|9(?:09|[1-3])|[2-7])|[24-8]"],
43816			"($1)","0$CC $1"],[,"(\\d{3})(\\d{7})","$1 $2",["3"],,"0$CC $1"],[,"(1)(\\d{3})(\\d{7})","$1-$2-$3",["1(?:80|9[04])","1(?:800|9(?:0[01]|4[78]))"],"0$1"]],[[,"(\\d)(\\d{7})","$1 $2",["1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","1(?:8[2-9]|9(?:09|[1-3])|[2-7])|[24-8]"],"($1)","0$CC $1"],[,"(\\d{3})(\\d{7})","$1 $2",["3"],,"0$CC $1"],[,"(1)(\\d{3})(\\d{7})","$1 $2 $3",["1(?:80|9[04])","1(?:800|9(?:0[01]|4[78]))"]]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CR:[,[,,"[24-9]\\d{7,9}",,
43817			,,,,,[8,10]],[,,"2[0-24-7]\\d{6}",,,,"22123456",,,[8]],[,,"5(?:0[01]|7[0-3])\\d{5}|6(?:[0-4]\\d{3}|500[01])\\d{3}|(?:7[0-3]|8[3-9])\\d{6}",,,,"83123456",,,[8]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"90[059]\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"210[0-6]\\d{4}|4\\d{7}|5100\\d{4}",,,,"40001234",,,[8]],"CR",506,"00",,,,"(19(?:0[012468]|1[09]|20|66|77|99))",,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[24-7]|8[3-9]"],,"$CC $1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["[89]0"],
43818			,"$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CU:[,[,,"[2-57]\\d{5,7}",,,,,,,[6,7,8],[4,5]],[,,"2[1-4]\\d{5,6}|3(?:1\\d{6}|[23]\\d{4,6})|4(?:[125]\\d{5,6}|[36]\\d{6}|[78]\\d{4,6})|7\\d{6,7}",,,,"71234567",,,,[4,5]],[,,"5\\d{7}",,,,"51234567",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CU",53,"119","0",,,"0",,,,[[,"(\\d)(\\d{6,7})","$1 $2",["7"],"(0$1)"],[,"(\\d{2})(\\d{4,6})","$1 $2",["[2-4]"],"(0$1)"],[,"(\\d)(\\d{7})",
43819			"$1 $2",["5"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CV:[,[,,"[259]\\d{6}",,,,,,,[7]],[,,"2(?:2[1-7]|3[0-8]|4[12]|5[1256]|6\\d|7[1-3]|8[1-5])\\d{4}",,,,"2211234"],[,,"(?:9\\d|59)\\d{5}",,,,"9911234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CV",238,"0",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CW:[,[,,"[169]\\d{6,7}",,,,,,,[7,8]],[,,"9(?:[48]\\d{2}|50\\d|7(?:2[0-24]|[34]\\d|6[35-7]|77|8[7-9]))\\d{4}",
43820			,,,"94151234",,,[8]],[,,"9(?:5(?:[12467]\\d|3[01])|6(?:[15-9]\\d|3[01]))\\d{4}",,,,"95181234",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"60[0-2]\\d{4}",,,,"6001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CW",599,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[13-7]"]],[,"(9)(\\d{3})(\\d{4})","$1 $2 $3",["9"]]],,[,,"955\\d{5}",,,,"95581234",,,[8]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CX:[,[,,"[1458]\\d{5,9}",,,,,,,[6,7,8,9,10]],[,,"89164\\d{4}",,,,"891641234",,,[9],[8]],[,,"14(?:5\\d|71)\\d{5}|4(?:[0-2]\\d|3[0-57-9]|4[47-9]|5[0-25-9]|6[6-9]|7[02-9]|8[147-9]|9[017-9])\\d{6}",
43821			,,,"412345678",,,[9]],[,,"180(?:0\\d{3}|2)\\d{3}",,,,"1800123456",,,[7,10]],[,,"190[0126]\\d{6}",,,,"1900123456",,,[10]],[,,"13(?:00\\d{2})?\\d{4}",,,,"1300123456",,,[6,8,10]],[,,"500\\d{6}",,,,"500123456",,,[9]],[,,"550\\d{6}",,,,"550123456",,,[9]],"CX",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88))?001[14-689]","0",,,"0",,"0011",,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CY:[,[,,"[257-9]\\d{7}",,,,,,,[8]],[,,"2[2-6]\\d{6}",,,,"22345678"],[,,"9[4-79]\\d{6}",,,,"96123456"],
43822			[,,"800\\d{5}",,,,"80001234"],[,,"90[09]\\d{5}",,,,"90012345"],[,,"80[1-9]\\d{5}",,,,"80112345"],[,,"700\\d{5}",,,,"70012345"],[,,,,,,,,,[-1]],"CY",357,"00",,,,,,,,[[,"(\\d{2})(\\d{6})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"(?:50|77)\\d{6}",,,,"77123456"],,,[,,,,,,,,,[-1]]],CZ:[,[,,"[2-8]\\d{8}|9\\d{8,11}",,,,,,,[9,10,11,12]],[,,"2\\d{8}|(?:3[1257-9]|4[16-9]|5[13-9])\\d{7}",,,,"212345678",,,[9]],[,,"(?:60[1-8]|7(?:0[2-5]|[2379]\\d))\\d{6}",,,,"601123456",,,[9]],[,,"800\\d{6}",,,,"800123456",
43823			,,[9]],[,,"9(?:0[05689]|76)\\d{6}",,,,"900123456",,,[9]],[,,"8[134]\\d{7}",,,,"811234567",,,[9]],[,,"70[01]\\d{6}",,,,"700123456",,,[9]],[,,"9[17]0\\d{6}",,,,"910123456",,,[9]],"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2-8]|9[015-7]"]],[,"(96\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["96"]],[,"(9\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["9[36]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"9(?:5\\d|7[234])\\d{6}",,,,"972123456",,,[9]],,,[,,"9(?:3\\d{9}|6\\d{7,10})",,,
43824			,"93123456789"]],DE:[,[,,"[1-35-9]\\d{3,14}|4(?:[0-8]\\d{3,12}|9(?:[0-37]\\d|4(?:[1-35-8]|4\\d?)|5\\d{1,2}|6[1-8]\\d?)\\d{2,8})",,,,,,,[4,5,6,7,8,9,10,11,12,13,14,15],[3]],[,,"2\\d{5,13}|3(?:0\\d{3,13}|2\\d{9}|[3-9]\\d{4,13})|4(?:0\\d{3,12}|\\d{5,13})|5(?:0[2-8]|[1256]\\d|[38][0-8]|4\\d{0,2}|[79][0-7])\\d{3,11}|6(?:\\d{5,13}|9\\d{3,12})|7(?:0[2-8]|[1-9]\\d)\\d{3,10}|8(?:0[2-9]|[1-8]\\d|9\\d?)\\d{3,10}|9(?:0[6-9]\\d{3,10}|1\\d{4,12}|[2-9]\\d{4,11})",,,,"30123456",,,[5,6,7,8,9,10,11,12,13,14,15],[3,
43825			4]],[,,"1(?:5[0-25-9]\\d{8}|6[023]\\d{7,8}|7\\d{8,9})",,,,"15123456789",,,[10,11]],[,,"800\\d{7,12}",,,,"8001234567890",,,[10,11,12,13,14,15]],[,,"137[7-9]\\d{6}|900(?:[135]\\d{6}|9\\d{7})",,,,"9001234567",,,[10,11]],[,,"1(?:3(?:7[1-6]\\d{6}|8\\d{4})|80\\d{5,11})",,,,"18012345",,,[7,8,9,10,11,12,13,14]],[,,"700\\d{8}",,,,"70012345678",,,[11]],[,,,,,,,,,[-1]],"DE",49,"00","0",,,"0",,,,[[,"(1\\d{2})(\\d{7,8})","$1 $2",["1[67]"],"0$1"],[,"(15\\d{3})(\\d{6})","$1 $2",["15[0568]"],"0$1"],[,"(1\\d{3})(\\d{7})",
43826			"$1 $2",["15"],"0$1"],[,"(\\d{2})(\\d{3,11})","$1 $2",["3[02]|40|[68]9"],"0$1"],[,"(\\d{3})(\\d{3,11})","$1 $2",["2(?:\\d1|0[2389]|1[24]|28|34)|3(?:[3-9][15]|40)|[4-8][1-9]1|9(?:06|[1-9]1)"],"0$1"],[,"(\\d{4})(\\d{2,11})","$1 $2",["[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:[3569][02-46-9]|4[2-4679]|7[2-467]|8[2-46-8])","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:3(?:0[1-467]|2[127-9]|3[124578]|[46][1246]|7[1257-9]|8[1256]|9[145])|4(?:2[135]|3[1357]|4[13578]|6[1246]|7[1356]|9[1346])|5(?:0[14]|2[1-3589]|3[1357]|4[1246]|6[1-4]|7[1346]|8[13568]|9[1246])|6(?:0[356]|2[1-489]|3[124-6]|4[1347]|6[13]|7[12579]|8[1-356]|9[135])|7(?:2[1-7]|3[1357]|4[145]|6[1-5]|7[1-4])|8(?:21|3[1468]|4[1347]|6[0135-9]|7[1467]|8[136])|9(?:0[12479]|2[1358]|3[1357]|4[134679]|6[1-9]|7[136]|8[147]|9[1468]))"],
43827			"0$1"],[,"(3\\d{4})(\\d{1,10})","$1 $2",["3"],"0$1"],[,"(800)(\\d{7,12})","$1 $2",["800"],"0$1"],[,"(\\d{3})(\\d)(\\d{4,10})","$1 $2 $3",["(?:18|90)0|137","1(?:37|80)|900[1359]"],"0$1"],[,"(1\\d{2})(\\d{5,11})","$1 $2",["181"],"0$1"],[,"(18\\d{3})(\\d{6})","$1 $2",["185","1850","18500"],"0$1"],[,"(18\\d{2})(\\d{7})","$1 $2",["18[68]"],"0$1"],[,"(18\\d)(\\d{8})","$1 $2",["18[2-579]"],"0$1"],[,"(700)(\\d{4})(\\d{4})","$1 $2 $3",["700"],"0$1"],[,"(138)(\\d{4})","$1 $2",["138"],"0$1"],[,"(15[013-68])(\\d{2})(\\d{8})",
43828			"$1 $2 $3",["15[013-68]"],"0$1"],[,"(15[279]\\d)(\\d{2})(\\d{7})","$1 $2 $3",["15[279]"],"0$1"],[,"(1[67]\\d)(\\d{2})(\\d{7,8})","$1 $2 $3",["1(?:6[023]|7)"],"0$1"]],,[,,"16(?:4\\d{1,10}|[89]\\d{1,11})",,,,"16412345",,,[4,5,6,7,8,9,10,11,12,13,14]],,,[,,,,,,,,,[-1]],[,,"18(?:1\\d{5,11}|[2-9]\\d{8})",,,,"18500123456",,,[8,9,10,11,12,13,14]],,,[,,"1(?:5(?:(?:2\\d55|7\\d99|9\\d33)\\d{7}|(?:[034568]00|113)\\d{8})|6(?:013|255|399)\\d{7,8}
vendor: 6,907 bytes, lines 43828-43841
43828|7(?:[015]13|[234]55|[69]33|[78]99)\\d{7,8})",,,,"177991234567",
43829			,,[12,13]]],DJ:[,[,,"[27]\\d{7}",,,,,,,[8]],[,,"2(?:1[2-5]|7[45])\\d{5}",,,,"21360003"],[,,"77\\d{6}",,,,"77831001"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"DJ",253,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DK:[,[,,"[2-9]\\d{7}",,,,,,,[8]],[,,"(?:[2-7]\\d|8[126-9]|9[1-36-9])\\d{6}",,,,"32123456"],[,,"(?:[2-7]\\d|8[126-9]|9[1-36-9])\\d{6}",,,,"20123456"],[,,"80\\d{6}",
43830			,,,"80123456"],[,,"90\\d{6}",,,,"90123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"DK",45,"00",,,,,,,1,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DM:[,[,,"[57-9]\\d{9}",,,,,,,[10],[7]],[,,"767(?:2(?:55|66)|4(?:2[01]|4[0-25-9])|50[0-4]|70[1-3])\\d{4}",,,,"7674201234",,,,[7]],[,,"767(?:2(?:[234689]5|7[5-7])|31[5-7]|61[1-7])\\d{4}",,,,"7672251234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],
43831			[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"DM",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"767",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DO:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"8(?:[04]9[2-9]\\d{6}|29(?:2(?:[0-59]\\d|6[04-9]|7[0-27]|8[0237-9])|3(?:[0-35-9]\\d|4[7-9])|[45]\\d{2}|6(?:[0-27-9]\\d|[3-5][1-9]|6[0135-8])|7(?:0[013-9]|[1-37]\\d|4[1-35689]|5[1-4689]|6[1-57-9]|8[1-79]|9[1-8])|8(?:0[146-9]|1[0-48]|[248]\\d|3[1-79]|5[01589]|6[013-68]|7[124-8]|9[0-8])|9(?:[0-24]\\d|3[02-46-9]|5[0-79]|60|7[0169]|8[57-9]|9[02-9]))\\d{4})",
43832			,,,"8092345678",,,,[7]],[,,"8[024]9[2-9]\\d{6}",,,,"8092345678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"DO",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"8[024]9",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DZ:[,[,,"(?:[1-4]|[5-9]\\d)\\d{7}",,,,,,,[8,9]],[,,"(?:1\\d|2[013-79]|3[0-8]|4[0135689])\\d{6}|9619\\d{5}",,,,"12345678"],[,,"(?:5[4-6]|7[7-9])\\d{7}|6(?:[569]\\d|7[0-6])\\d{6}",
43833			,,,"551234567",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"80[3-689]1\\d{5}",,,,"808123456",,,[9]],[,,"80[12]1\\d{5}",,,,"801123456",,,[9]],[,,,,,,,,,[-1]],[,,"98[23]\\d{6}",,,,"983123456",,,[9]],"DZ",213,"00","0",,,"0",,,,[[,"([1-4]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[1-4]"],"0$1"],[,"([5-8]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[5-8]"],"0$1"],[,"(9\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["9"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
43834		EC:[,[,,"1\\d{9,10}|[2-8]\\d{7}|9\\d{8}",,,,,,,[8,9,10,11],[7]],[,,"[2-7][2-7]\\d{6}",,,,"22123456",,,[8],[7]],[,,"9(?:(?:39|[45][89]|7[7-9]|[89]\\d)\\d|6(?:[017-9]\\d|2[0-4]))\\d{5}",,,,"991234567",,,[9]],[,,"1800\\d{6,7}",,,,"18001234567",,,[10,11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"[2-7]890\\d{4}",,,,"28901234",,,[8]],"EC",593,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2-$3",["[247]|[356][2-8]"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["9"],"0$1"],[,"(1800)(\\d{3})(\\d{3,4})",
43835			"$1 $2 $3",["1"],"$1"]],[[,"(\\d)(\\d{3})(\\d{4})","$1-$2-$3",["[247]|[356][2-8]"]],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["9"],"0$1"],[,"(1800)(\\d{3})(\\d{3,4})","$1 $2 $3",["1"],"$1"]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],EE:[,[,,"[3-9]\\d{6,7}|800\\d{6,7}",,,,,,,[7,8,10]],[,,"(?:3[23589]|4[3-8]|6\\d|7[1-9]|88)\\d{5}",,,,"3212345",,,[7]],[,,"(?:5\\d|8[1-5])\\d{6}|5(?:[02]\\d{2}|1(?:[0-8]\\d|95)|5[0-478]\\d|64[0-4]|65[1-589])\\d{3}",,,,"51234567",,,[7,8]],[,,"800(?:0\\d{3}|1\\d|[2-9])\\d{3}",
43836			,,,"80012345"],[,,"(?:40\\d{2}|900)\\d{4}",,,,"9001234",,,[7,8]],[,,,,,,,,,[-1]],[,,"70[0-2]\\d{5}",,,,"70012345",,,[8]],[,,,,,,,,,[-1]],"EE",372,"00",,,,,,,,[[,"([3-79]\\d{2})(\\d{4})","$1 $2",["[369]|4[3-8]|5(?:[0-2]|5[0-478]|6[45])|7[1-9]","[369]|4[3-8]|5(?:[02]|1(?:[0-8]|95)|5[0-478]|6(?:4[0-4]|5[1-589]))|7[1-9]"]],[,"(70)(\\d{2})(\\d{4})","$1 $2 $3",["70"]],[,"(8000)(\\d{3})(\\d{3})","$1 $2 $3",["800","8000"]],[,"([458]\\d{3})(\\d{3,4})","$1 $2",["40|5|8(?:00|[1-5])","40|5|8(?:00[1-9]|[1-5])"]]],
43837			,[,,,,,,,,,[-1]],,,[,,"800[2-9]\\d{3}",,,,"8002123",,,[7]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],EG:[,[,,"1\\d{4,9}|[2456]\\d{8}|3\\d{7}|[89]\\d{8,9}",,,,,,,[8,9,10],[7]],[,,"(?:1(?:3[23]\\d|5(?:[23]|9\\d))|2[2-4]\\d{2}|3\\d{2}|4(?:0[2-5]|[578][23]|64)\\d|5(?:0[2-7]|[57][23])\\d|6[24-689]3\\d|8(?:2[2-57]|4[26]|6[237]|8[2-4])\\d|9(?:2[27]|3[24]|52|6[2356]|7[2-4])\\d)\\d{5}",,,,"234567890",,,[8,9],[7]],[,,"1(?:0[0-269]|1[0-245]|2[0-278]|55)\\d{7}",,,,"1001234567",,,[10]],[,,"800\\d{7}",,,,"8001234567",
43838			,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"EG",20,"00","0",,,"0",,,,[[,"(\\d)(\\d{7,8})","$1 $2",["[23]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1[012]|[89]00"],"0$1"],[,"(\\d{2})(\\d{6,7})","$1 $2",["1[35]|[4-6]|[89][2-9]"],"0$1"],[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3",["155"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],EH:[,[,,"[5-9]\\d{8}",,,,,,,[9]],[,,"528[89]\\d{5}",,,,"528812345"],[,,"(?:6(?:[0-79]\\d|8[0-247-9])|7(?:[07][07]|6[12]))\\d{6}",
43839			,,,"650123456"],[,,"80\\d{7}",,,,"801234567"],[,,"89\\d{7}",,,,"891234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5924[01]\\d{4}",,,,"592401234"],"EH",212,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,"528[89]",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ER:[,[,,"[178]\\d{6}",,,,,,,[7],[6]],[,,"1(?:1[12568]|20|40|55|6[146])\\d{4}|8\\d{6}",,,,"8370362",,,,[6]],[,,"17[1-3]\\d{4}|7\\d{6}",,,,"7123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ER",291,"00","0",,,"0",
43840			,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ES:[,[,,"[5-9]\\d{8}",,,,,,,[9]],[,,"8(?:[1356]\\d|[28][0-8]|[47][1-9])\\d{6}|9(?:[135]\\d{7}|[28][0-8]\\d{6}|4[1-9]\\d{6}|6(?:[0-8]\\d{6}|9(?:0(?:[0-57-9]\\d{4}|6(?:0[0-8]|1[1-9]|[2-9]\\d)\\d{2})|[1-9]\\d{5}))|7(?:[124-9]\\d{2}|3(?:[0-8]\\d|9[1-9]))\\d{4})",,,,"810123456"],[,,"(?:6\\d{6}|7[1-48]\\d{5}|9(?:6906(?:09|10)|7390\\d{2}))\\d{2}",,,,"612345678"],[,,"[89]00\\d{6}",,,,"800123456"],
43841			[,,"80[367]\\d{6}",,,,"803123456"],[,,"90[12]\\d{6}",,,,"901123456"],[,,"70\\d{7}",,,,"701234567"],[,,,,,,,,,[-1]],"ES",34,"00",,,,,,,,[[,"([89]00)(\\d{3})(\\d{3})","$1 $2 $3",["[89]00"]],[,"([5-9]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[568]|[79][0-8]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"51\\d{7}",,,,"511234567"],,,[,,,,,,,,,[-1]]],ET:[,[,,"[1-59]\\d{8}",,,,,,,[9],[7]],[,,"(?:11(?:1(?:1[124]|2[2-57]|3[1-5]|5[5-8]|8[6-8])|2(?:13|3[6-8]|5[89]|7[05-9]|8[2-6])|3(?:2[01
43841]|3[0-289]|4[1289]|7[1-4]|87)|4(?:1[69]|3[2-49]|4[0-3]|6[5-8])|5(?:1[578]|44|5[0-4])|6(?:18|2[69]|39|4[5-7]|5[1-5]|6[0-59]|8[015-8]))|2(?:2(?:11[1-9]|22[0-7]|33\\d|44[1467]|66[1-68])|5(?:11[124-6]|33[2-8]|44[1467]|55[14]|66[1-3679]|77[124-79]|880))|3(?:3(?:11[0-46-8]|22[0-6]|33[0134689]|44[04]|55[0-6]|66[01467])|4(?:44[0-8]|55[0-69]|66[0-3]|77[1-5]))|4(?:6(?:22[0-24-7]|33[1-5]|44[13-69]|55[14-689]|660|88[1-4])|7(?:11[1-9]|22[1-9]|33[13-7]|44[13-6]|55[1-689]))|5(?:7(?:227|55[05]|(?:66|77)[14-8])|8(?:11[149]|22[013-79]|33[0-68]|44[013-8]|550|66[1-5]|77\\d)))\\d{4}",
43842			,,,"111112345",,,,[7]],[,,"9(?:[1-46-8]\\d|5[89])\\d{6}",,,,"911234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ET",251,"00","0",,,"0",,,,[[,"([1-59]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FI:[,[,,"[16]\\d{6,9}|2\\d{4,9}|[35]\\d{5,9}|4\\d{7,10}|7\\d{7,9}|[89]\\d{6,8}",,,,,,,[5,6,7,8,9,10,11]],[,,"1[3-79][1-8]\\d{4,6}|[235689][1-8]\\d{5,7}",,,,"131234567",,,[7,8,9]],[,,"4(?:[0-8]\\d{6,8}|9\\d{9})|50\\d{4,8}",
43843			,,,"412345678",,,[6,7,8,9,10,11]],[,,"800\\d{5,6}",,,,"800123456",,,[8,9]],[,,"[67]00\\d{5,6}",,,,"600123456",,,[8,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FI",358,"00|99(?:[02469]|5(?:11|33|5[59]|88|9[09]))","0",,,"0",,"00",,[[,"(\\d{3})(\\d{3,7})","$1 $2",["(?:[1-3]00|[6-8]0)"],"0$1"],[,"(116\\d{3})","$1",["116"],"$1"],[,"(\\d{2})(\\d{3,9})","$1 $2",["1(?:0[1-9]|[3-9])|2(?:0[1-9]|9)|30[1-9]|4|50|7(?:[13]|5[03-9])"],"0$1"],[,"(75\\d{3})","$1",["75[12]"],"0$1"],[,"(\\d)(\\d{5,9})","$1 $2",
43844			["[235689][1-8]"],"0$1"],[,"(39\\d)(\\d{3})(\\d{3})","$1 $2 $3",["39"],"0$1"]],[[,"(\\d{3})(\\d{3,7})","$1 $2",["(?:[1-3]00|[6-8]0)"],"0$1"],[,"(116\\d{3})","$1",["116"],"$1"],[,"(\\d{2})(\\d{3,9})","$1 $2",["1(?:0[1-9]|[3-9])|2(?:0[1-9]|9)|30[1-9]|4|50|7(?:[13]|5[03-9])"],"0$1"],[,"(\\d)(\\d{5,9})","$1 $2",["[235689][1-8]"],"0$1"],[,"(39\\d)(\\d{3})(\\d{3})","$1 $2 $3",["39"],"0$1"]],[,,,,,,,,,[-1]],1,,[,,"100\\d{4,6}|20(?:0\\d{4,6}|2[023]\\d{4,5}|9[89]\\d{1,6})|300\\d{3,7}|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",
43845			,,,"1001234",,,[5,6,7,8,9,10]],[,,"10(?:0\\d{4,6}|[1-9]\\d{5,7})|2(?:0(?:0\\d{4,6}|[13-8]\\d{5,7}|2(?:[023]\\d{4,5}|[14-9]\\d{4,6})|9(?:[0-7]\\d{4,6}|[89]\\d{1,6}))|9\\d{5,8})|3(?:0(?:0\\d{3,7}|[1-57-9]\\d{5,7}|6(?:\\d{3}|\\d{5,7}))|93\\d{5,7})|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",,,,"10112345",,,[5,6,7,8,9,10]],,,[,,,,,,,,,[-1]]],FJ:[,[,,"[35-9]\\d{6}|0\\d{10}",,,,,,,[7,11]],[,,"(?:3[0-5]|6[25-7]|8[58])\\d{5}",,,,"3212345",,,[7]],[,,"(?:5[018]|[79]\\d|8[034679])\\d{5}",
43846			,,,"7012345",,,[7]],[,,"0800\\d{7}",,,,"08001234567",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FJ",679,"0(?:0|52)",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1 $2",["[35-9]"]],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FK:[,[,,"[2-7]\\d{4}",,,,,,,[5]],[,,"[2-47]\\d{4}",,,,"31234"],[,,"[56]\\d{4}",,,,"51234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FK",500,"00",
43847			,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FM:[,[,,"[39]\\d{6}",,,,,,,[7]],[,,"3[2357]0[1-9]\\d{3}|9[2-6]\\d{5}",,,,"3201234"],[,,"3[2357]0[1-9]\\d{3}|9[2-7]\\d{5}",,,,"3501234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FM",691,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FO:[,[,,"[2-9]\\d{5}",,,,,,,[6]],[,,"(?:20|[3-4]\\d|8[19])\\d{4}",,,,"201234"],[,,"(?:[27][1-9]|5\\d)\\d{4}",
43848			,,,"211234"],[,,"80[257-9]\\d{3}",,,,"802123"],[,,"90(?:[1345][15-7]|2[125-7]|99)\\d{2}",,,,"901123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:6[0-36]|88)\\d{4}",,,,"601234"],"FO",298,"00",,,,"(10(?:01|[12]0|88))",,,,[[,"(\\d{6})","$1",,,"$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FR:[,[,,"[1-9]\\d{8}",,,,,,,[9]],[,,"[1-5]\\d{8}",,,,"123456789"],[,,"(?:6\\d|7[3-9])\\d{7}",,,,"612345678"],[,,"80[0-5]\\d{6}",,,,"801234567"],[,,"89[1-37-9]\\d{6}",,,,"891123456"],[,
43849			,"8(?:1[0-29]|2[0156]|84|90)\\d{6}",,,,"810123456"],[,,,,,,,,,[-1]],[,,"9\\d{8}",,,,"912345678"],"FR",33,"00","0",,,"0",,,,[[,"([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["[1-79]"],"0$1"],[,"(1\\d{2})(\\d{3})","$1 $2",["11"],"$1"],[,"(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8"],"0 $1"]],[[,"([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["[1-79]"],"0$1"],[,"(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8"],"0 $1"]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"80[6-9]\\d{6}",
43850			,,,"806123456"],,,[,,,,,,,,,[-1]]],GA:[,[,,"0?\\d{7}",,,,,,,[7,8]],[,,"01\\d{6}",,,,"01441234",,,[8]],[,,"0?[2-7]\\d{6}",,,,"06031234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GA",241,"00",,,,,,,,[[,"(\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2-7]"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GB:[,[,,"\\d{7,10}",,,,,,,[7,9,10],[4,5,6,8]],[,,"2(?:0[01378]|3[0189]|4[017]|8[0-46-9]|9[0-2])\\d{7}|1(?:1(?:3[0-48]|[46][0-4]|5[0-26-9]|[78][0-49])|21[0-7]|31[0-8]|[4-69]1\\d)\\d{6}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-47-9]|7[013-9]|9\\d)|3(?:0\\d|[25][02-9]|3[02-579]|[468][0-46-9]|7[1-35-79]|9[2-578])|4(?:0[03-9]|[28][02-57-9]|[37]\\d|4[02-69]|5[0-8]|[69][0-79])|5(?:0[1-35-9]|2[024-9]|3[015689]|4[02-9]|5[03-9]|6\\d|7[0-35-9]|8[0-468]|9[0-57-9])|6(?:0[034689]|2[0-35689]|[38][013-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|9[0124578])|7(?:0[0246-9]|2\\d|3[0236-8]|4[03-9]|5[0-46-9]|6[013-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-57-9]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[02-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-57-9]|4[2-9]|5[0-579]|6[2-47-9]|7[0-24578]|8\\d|9[2-57]))\\d{6}|1(?:2(?:0(?:46[1-4]|87[2-9])|545[1-79]|76(?:2\\d|3[1-8]|6[1-6])|9(?:7(?:2[0-4]|3[2-5])|8(?:2[2-8]|7[0-47-9]|8[345])))|3(?:638[2-5]|647[23]|8(?:47[04-9]|64[0157-9]))|4(?:044[1-7]|20(?:2[23]|8\\d)|6(?:0(?:30|5[2
43850-57]|6[1-8]|7[2-8])|140)|8(?:052|87[123]))|5(?:24(?:3[2-79]|6\\d)|276\\d|6(?:26[06-9]|686))|6(?:06(?:4\\d|7[4-79])|295[567]|35[34]\\d|47(?:24|61)|59(?:5[08]|6[67]|74)|955[0-4])|7(?:26(?:6[13-9]|7[0-7])|442\\d|50(?:2[0-3]|[3-68]2|76))|8(?:27[56]\\d|37(?:5[2-5]|8[239])|84(?:3[2-58]))|9(?:0(?:0(?:6[1-8]|85)|52\\d)|3583|4(?:66[1-8]|9(?:2[01]|81))|63(?:23|3[1-4])|9561))\\d{3}|176888[2-46-8]\\d{2}|16977[23]\\d{3}",
43851			,,,"1212345678",,,[9,10],[4,5,6,7,8]],[,,"7(?:[1-3]\\d{3}|4(?:[0-46-9]\\d{2}|5(?:[0-689]\\d|7[0-57-9]))|5(?:0[0-8]|[13-9]\\d|2[0-35-9])\\d|7(?:0(?:0[01]|[1-9]\\d)|[1-7]\\d{2}|8[02-9]\\d|9[0-689]\\d)|8(?:[014-9]\\d|[23][0-8])\\d|9(?:[024-9]\\d{2}|1(?:[02-9]\\d|1[028])|3[0-689]\\d))\\d{5}",,,,"7400123456",,,[10]],[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}",,,,"8001234567"],[,,"(?:87[123]|9(?:[01]\\d|8[2349]))\\d{7}",,,,"9012345678",,,[10]],[,,"8(?:4(?:5464\\d|[2-5]\\d{7})|70\\d{7})",,,,"8431234567",
43852			,,[7,10]],[,,"70\\d{8}",,,,"7012345678",,,[10]],[,,"56\\d{8}",,,,"5612345678",,,[10]],"GB",44,"00","0"," x",,"0",,,,[[,"(7\\d{3})(\\d{6})","$1 $2",["7(?:[1-57-9]|62)","7(?:[1-57-9]|624)"],"0$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["2|5[56]|7[06]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1(?:1|\\d1)|3|9[018]"],"0$1"],[,"(\\d{5})(\\d{4,5})","$1 $2",["1(?:38|5[23]|69|76|94)","1(?:387|5(?:24|39)|697|768|946)","1(?:3873|5(?:242|39[456])|697[347]|768[347]|9467)"],"0$1"],[,"(1\\d{3})(\\d{5,6})",
43853			"$1 $2",["1"],"0$1"],[,"(800)(\\d{4})","$1 $2",["800","8001","80011","800111","8001111"],"0$1"],[,"(845)(46)(4\\d)","$1 $2 $3",["845","8454","84546","845464"],"0$1"],[,"(8\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["8(?:4[2-5]|7[0-3])"],"0$1"],[,"(80\\d)(\\d{3})(\\d{4})","$1 $2 $3",["80"],"0$1"],[,"([58]00)(\\d{6})","$1 $2",["[58]00"],"0$1"]],,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}",,,,"7640123456",,,[10]],1,,[,,,,,,,,,[-1]],[,,"(?:3[0347]|55)\\d{8}",,,,"5512345678",,,[10]],,,[,
43854			,,,,,,,,[-1]]],GD:[,[,,"[4589]\\d{9}",,,,,,,[10],[7]],[,,"473(?:2(?:3[0-2]|69)|3(?:2[89]|86)|4(?:[06]8|3[5-9]|4[0-49]|5[5-79]|68|73|90)|63[68]|7(?:58|84)|800|938)\\d{4}",,,,"4732691234",,,,[7]],[,,"473(?:4(?:0[2-79]|1[04-9]|2[0-5]|58)|5(?:2[01]|3[3-8])|901)\\d{4}",,,,"4734031234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"GD",1,"011","1",,,"1",,,
43855			,,,[,,,,,,,,,[-1]],,"473",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GE:[,[,,"[34578]\\d{8}",,,,,,,[9],[6]],[,,"(?:3(?:[256]\\d|4[124-9]|7[0-4])|4(?:1\\d|2[2-7]|3[1-79]|4[2-8]|7[239]|9[1-7]))\\d{6}",,,,"322123456",,,,[6]],[,,"5(?:[14]4|5[0157-9]|68|7[0147-9]|9[0-35-9])\\d{6}",,,,"555123456"],[,,"800\\d{6}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"706\\d{6}",,,,"706123456"],"GE",995,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[348]"],"0$1"],
43856			[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["7"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["5"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"706\\d{6}",,,,"706123456"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GF:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"594(?:10|2[012457-9]|3[0-57-9]|4[3-9]|5[7-9]|6[0-3]|9[014])\\d{4}",,,,"594101234"],[,,"694(?:[0249]\\d|1[2-9]|3[0-48])\\d{4}",,,,"694201234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GF",594,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})",
43857			"$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GG:[,[,,"[135789]\\d{6,9}",,,,,,,[7,9,10],[6]],[,,"1481[25-9]\\d{5}",,,,"1481256789",,,[10],[6]],[,,"7(?:781\\d|839\\d|911[17])\\d{5}",,,,"7781123456",,,[10]],[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}",,,,"8001234567"],[,,"(?:87[123]|9(?:[01]\\d|8[0-3]))\\d{7}",,,,"9012345678",,,[10]],[,,"8(?:4(?:5464\\d|[2-5]\\d{7})|70\\d{7})",,,,"8431234567",,,[7,10]],[,,"70\\d{8}",,,,"7012345678",,,[10]],[,,"56\\d{8}",
43858			,,,"5612345678",,,[10]],"GG",44,"00","0",,,"0",,,,,,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}",,,,"7640123456",,,[10]],,,[,,,,,,,,,[-1]],[,,"(?:3[0347]|55)\\d{8}",,,,"5512345678",,,[10]],,,[,,,,,,,,,[-1]]],GH:[,[,,"[235]\\d{8}|8\\d{7}
43858",,,,,,,[8,9],[7]],[,,"3(?:0(?:[237]\\d|80)|[167](?:2[0-6]|7\\d|80)|2(?:2[0-5]|7\\d|80)|3(?:2[0-3]|7\\d|80)|4(?:2[013-9]|3[01]|7\\d|80)|5(?:2[0-7]|7\\d|80)|8(?:2[0-2]|7\\d|80)|9(?:[28]0|7\\d))\\d{5}",,,,"302345678",,,[9],[7]],[,,"(?:2[034678]\\d|5(?:[0457]\\d|6[01]))\\d{6}",
43859			,,,"231234567",,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GH",233,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[235]"],"0$1"],[,"(\\d{3})(\\d{5})","$1 $2",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,"800\\d{5}",,,,"80012345",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GI:[,[,,"[256]\\d{7}",,,,,,,[8]],[,,"2(?:00\\d{2}|1(?:6[24-7]\\d|90[0-2])|2(?:2[2457]\\d|50[0-2]))\\d{3}",,,,"20012345"],[,,"(?:5[46-8]|62)\\d{6}",,,,"57123456"],
43860			[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GI",350,"00",,,,,,,,[[,"(\\d{3})(\\d{5})","$1 $2",["2"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GL:[,[,,"[1-689]\\d{5}",,,,,,,[6]],[,,"(?:19|3[1-6]|6[14689]|8[14-79]|9\\d)\\d{4}",,,,"321000"],[,,"[245][2-9]\\d{4}",,,,"221234"],[,,"80\\d{4}",,,,"801234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3[89]\\d{4}",,,,"381234"],"GL",299,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3"]],
43861			,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GM:[,[,,"[2-9]\\d{6}",,,,,,,[7]],[,,"(?:4(?:[23]\\d{2}|4(?:1[024679]|[6-9]\\d))|5(?:54[0-7]|6(?:[67]\\d)|7(?:1[04]|2[035]|3[58]|48))|8\\d{3})\\d{3}",,,,"5661234"],[,,"[23679]\\d{6}",,,,"3012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GM",220,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GN:[,[,,"[367]\\d{7,8}",,,,,,,[8,
43862			9]],[,,"30(?:24|3[12]|4[1-35-7]|5[13]|6[189]|[78]1|9[1478])\\d{4}",,,,"30241234",,,[8]],[,,"6[02356]\\d{7}",,,,"601123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"722\\d{6}",,,,"722123456",,,[9]],"GN",224,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["3"]],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[67]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GP:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"590(?:0[13468]|1[012]|2[0-68]|3[28]|4[0-8]|5[579]|6[0189]|70|8[0-689]|9\\d)\\d{4}",
43863			,,,"590201234"],[,,"690(?:0[05-9]|[1-9]\\d)\\d{4}",,,,"690001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GP",590,"00","0",,,"0",,,,[[,"([56]90)(\\d{2})(\\d{4})","$1 $2-$3",,"0$1"]],,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GQ:[,[,,"[23589]\\d{8}",,,,,,,[9]],[,,"3(?:3(?:3\\d[7-9]|[0-24-9]\\d[46])|5\\d{2}[7-9])\\d{4}",,,,"333091234"],[,,"(?:222|55[15])\\d{6}",,,,"222123456"],[,,"80\\d[1-9]\\d{5}",,,,"800123456"],[,,"90\\d[1-9]\\d{5}",
43864			,,,"900123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GQ",240,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[235]"]],[,"(\\d{3})(\\d{6})","$1 $2",["[89]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GR:[,[,,"[26-9]\\d{9}",,,,,,,[10]],[,,"2(?:1\\d{2}|2(?:2[1-46-9]|3[1-8]|4[1-7]|5[1-4]|6[1-8]|7[1-5]|[89][1-9])|3(?:1\\d|2[1-57]|[35][1-3]|4[13]|7[1-7]|8[124-6]|9[1-79])|4(?:1\\d|2[1-8]|3[1-4]|4[13-5]|6[1-578]|9[1-5])|5(?:1\\d|[29][1-4]|3[1-5]|4[124]|5[1-6])|6(?:1\\d|3[1245]|4[1-7]|5[13-9]|[269][1-6]|7[14]|8[1-5])|7(?:1\\d|2[1-5]|3[1-6]|4[1-7]|5[1-57]|6[135]|9[125-7])|8(?:1\\d|2[1-5]|[34][1-4]|9[1-57]))\\d{6}",
43865			,,,"2123456789"],[,,"69\\d{8}",,,,"6912345678"],[,,"800\\d{7}",,,,"8001234567"],[,,"90[19]\\d{7}",,,,"9091234567"],[,,"8(?:0[16]|12|25)\\d{7}",,,,"8011234567"],[,,"70\\d{8}",,,,"7012345678"],[,,,,,,,,,[-1]],"GR",30,"00",,,,,,,,[[,"([27]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["21|7"]],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["2[2-9]1|[689]"]],[,"(2\\d{3})(\\d{6})","$1 $2",["2[2-9][02-9]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GT:[,[,,"[2-7]\\d{7}|1[89]\\d{9}",,,,,,,[8,11]],
43866			[,,"[267][2-9]\\d{6}",,,,"22456789",,,[8]],[,,"[345]\\d{7}",,,,"51234567",,,[8]],[,,"18[01]\\d{8}",,,,"18001112222",,,[11]],[,,"19\\d{9}",,,,"19001112222",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GT",502,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[2-7]"]],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["1"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GU:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"671(?:3(?:00|3[39]|4[349]|55|6[26])|4(?:56|7[1-9]|8[0236-9])|5(?:55|6[2-5]|88)|6(?:3[2-578]|4[24-9]|5[34]|78|8[5-9])|7(?:[079]7|2[0167]|3[45]|47|8[789])|8
vendor: 1,229 bytes, lines 43866-43869
43866(?:[2-5789]8|6[48])|9(?:2[29]|6[79]|7[179]|8[789]|9[78]))\\d{4}",
43867			,,,"6713001234",,,,[7]],[,,"671(?:3(?:00|3[39]|4[349]|55|6[26])|4(?:56|7[1-9]|8[0236-9])|5(?:55|6[2-5]|88)|6(?:3[2-578]|4[24-9]|5[34]|78|8[5-9])|7(?:[079]7|2[0167]|3[45]|47|8[789])|8(?:[2-5789]8|6[48])|9(?:2[29]|6[79]|7[179]|8[789]|9[78]))\\d{4}",,,,"6713001234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"GU",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],
43868			,"671",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GW:[,[,,"(?:4(?:0\\d{5}|4\\d{7})|9\\d{8})",,,,,,,[7,9]],[,,"443\\d{6}",,,,"443201234",,,[9]],[,,"9(?:5(?:5\\d|6[0-2])|6(?:5[0-2]|6\\d|9[012])|77\\d)\\d{5}",,,,"955012345",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"40\\d{5}",,,,"4012345",,,[7]],"GW",245,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["44|9[567]"]],[,"(\\d{3})(\\d{4})","$1 $2",["40"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,
43869			,[,,,,,,,,,[-1]]],GY:[,[,,"[2-46-9]\\d{6}",,,,,,,[7]],[,,"(?:2(?:1[6-9]|2[0-35-9]|3[1-4]|5[3-9]|6\\d|7[0-24-79])|3(?:2[25-9]|3\\d)|4(?:4[0-24]|5[56]
vendor: 10,548 bytes, lines 43869-43887
43869)|77[1-57])\\d{4}",,,,"2201234"],[,,"6\\d{6}",,,,"6091234"],[,,"(?:289|862)\\d{4}",,,,"2891234"],[,,"9008\\d{3}",,,,"9008123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GY",592,"001",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],HK:[,[,,"[235-7]\\d{7}|8\\d{7,8}|9\\d{4,10}",,,,,,,[5,
43870			6,7,8,9,11]],[,,"(?:2(?:[13-8]\\d|2[013-9]|9[0-24-9])|3(?:[1569][0-24-9]|4[0-246-9]|7[0-24-69]|89)|58[01])\\d{5}",,,,"21234567",,,[8]],[,,"(?:5(?:[1-59][0-46-9]|6[0-4689]|7[0-469])|6(?:0[1-9]|[1459]\\d|[2368][0-57-9]|7[0-79])|9(?:0[1-9]|1[02-9]|[2358][0-8]|[467]\\d))\\d{5}",,,,"51234567",,,[8]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"900(?:[0-24-9]\\d{7}|3\\d{1,4})",,,,"90012345678",,,[5,6,7,8,11]],[,,,,,,,,,[-1]],[,,"8(?:1[1-4679]|2[0-367]|3[02-47])\\d{5}",,,,"81123456",,,[8]],[,,,,,,,,,[-1]],"HK",
43871			852,"00(?:[126-9]|30|5[09])?",,,,,,"00",,[[,"(\\d{4})(\\d{4})","$1 $2",["[235-7]|[89](?:0[1-9]|[1-9])"]],[,"(800)(\\d{3})(\\d{3})","$1 $2 $3",["800"]],[,"(900)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4",["900"]],[,"(900)(\\d{2,5})","$1 $2",["900"]]],,[,,"7(?:1[0-369]|[23][0-37-9]|47|5[1578]|6[0235]|7[278]|8[236-9]|9[025-9])\\d{5}",,,,"71234567",,,[8]],,,[,,,,,,,,,[-1]],[,,"30(?:0[1-9]|[15-7]\\d|2[047]|89)\\d{4}",,,,"30161234",,,[8]],,,[,,,,,,,,,[-1]]],HN:[,[,,"[237-9]\\d{7}",,,,,,,[8]],[,,"2(?:2(?:0[019]|1[1-36]|[23]\\d|4[04-6]|5[57]|7[01389]|8[0146-9]|9[012])|4(?:07|2[3-59]|3[13-689]|4[0-68]|5[1-35])|5(?:16|4[03-5]|5\\d|6[4-6]|74)|6(?:[056]\\d|17|3[04]|4[0-378]|[78][0-8]|9[01])|7(?:6[46-9]|7[02-9]|8[034])|8(?:79|8[0-35789]|9[1-57-9]))\\d{4}",
43872			,,,"22123456"],[,,"[37-9]\\d{7}",,,,"91234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"HN",504,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1-$2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],HR:[,[,,"[1-7]\\d{5,8}|[89]\\d{6,8}",,,,,,,[6,7,8,9]],[,,"1\\d{7}|(?:2[0-3]|3[1-5]|4[02-47-9]|5[1-3])\\d{6,7}",,,,"12345678",,,[8,9],[6,7]],[,,"9(?:01\\d|[1259]\\d{2}|7(?:[0679]\\d|51)|8\\d{1,2})\\d{5}",,,,"921234567",,,[8,9]],[,,"80[01]\\d{4,6}",,,,
43873			"800123456",,,[7,8,9]],[,,"6(?:[01]\\d{0,2}|[459]\\d{2})\\d{4}",,,,"611234",,,[6,7,8]],[,,,,,,,,,[-1]],[,,"7[45]\\d{6}",,,,"74123456",,,[8]],[,,,,,,,,,[-1]],"HR",385,"00","0",,,"0",,,,[[,"(1)(\\d{4})(\\d{3})","$1 $2 $3",["1"],"0$1"],[,"([2-5]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[2-5]"],"0$1"],[,"(9\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["9"],"0$1"],[,"(6[01])(\\d{2})(\\d{2,3})","$1 $2 $3",["6[01]"],"0$1"],[,"([67]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[67]"],"0$1"],[,"(80[01])(\\d{2})(\\d{2,3})","$1 $2 $3",
43874			["8"],"0$1"],[,"(80[01])(\\d{3})(\\d{3})","$1 $2 $3",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"(?:62\\d?|72)\\d{6}",,,,"62123456",,,[8,9]],,,[,,,,,,,,,[-1]]],HT:[,[,,"[2-489]\\d{7}",,,,,,,[8]],[,,"2(?:2\\d|5[1-5]|81|9[149])\\d{5}",,,,"22453300"],[,,"[34]\\d{7}",,,,"34101234"],[,,"8\\d{7}",,,,"80012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:9(?:[67][0-4]|8[0-3589]|9\\d))\\d{5}",,,,"98901234"],"HT",509,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3"]],,[,,,,,,,,,[-1]],
43875			,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],HU:[,[,,"[1-9]\\d{7,8}",,,,,,,[8,9],[6]],[,,"(?:1\\d|2[2-9]|3[2-7]|4[24-9]|5[2-79]|6[23689]|7[2-9]|8[2-57-9]|9[2-69])\\d{6}",,,,"12345678",,,[8],[6]],[,,"(?:[257]0|3[01])\\d{7}",,,,"201234567",,,[9]],[,,"[48]0\\d{6}",,,,"80123456",,,[8]],[,,"9[01]\\d{6}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"21\\d{7}",,,,"211234567",,,[9]],"HU",36,"00","06",,,"06",,,,[[,"(1)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"($1)"],[,"(\\d{2})(\\d{3})(\\d{3,4})",
43876			"$1 $2 $3",["[2-9]"],"($1)"]],,[,,,,,,,,,[-1]],,,[,,"[48]0\\d{6}",,,,"80123456",,,[8]],[,,"38\\d{7}",,,,"381234567",,,[9]],,,[,,,,,,,,,[-1]]],ID:[,[,,"(?:[1-79]\\d{6,10}|8\\d{7,11})",,,,,,,[7,8,9,10,11,12],[5,6]],[,,"2(?:1(?:14\\d{3}|[0-8]\\d{6,7}|500\\d{3}|9\\d{6})|2\\d{6,8}|4\\d{7,8})|(?:2(?:[35][1-4]|6[0-8]|7[1-6]|8\\d|9[1-8])|3(?:1|[25][1-8]|3[1-68]|4[1-3]|6[1-3568]|7[0-469]|8\\d)|4(?:0[1-589]|1[01347-9]|2[0-36-8]|3[0-24-68]|43|5[1-378]|6[1-5]|7[134]|8[1245])|5(?:1[1-35-9]|2[25-8]|3[124-9]|4[1-3589]|5[1-46]|6[1-8])|6(?:19?|[25]\\d|3[1-69]|4[1-6])|7(?:02|[125][1-9]|[36]\\d|4[1-8]|7[0-36-9])|9(?:0[12]|1[013-8]|2[0-479]|5[125-8]|6[23679]|7[159]|8[01346]))\\d{5,8}",
43877			,,,"612345678",,,[7,8,9,10,11],[5,6]],[,,"(?:2(?:1(?:3[145]|4[01]|5[1-469]|60|8[0359]|9\\d)|2(?:88|9[1256])|3[1-4]9|4(?:36|91)|5(?:1[349]|[2-4]9)|6[0-7]9|7(?:[1-36]9|4[39])|8[1-5]9|9[1-48]9)|3(?:19[1-3]|2[12]9|3[13]9|4(?:1[69]|39)|5[14]9|6(?:1[69]|2[89])|709)|4[13]19|5(?:1(?:19|8[39])|4[129]9|6[12]9)|6(?:19[12]|2(?:[23]9|77))|7(?:1[13]9|2[15]9|419|5(?:1[89]|29)|6[15]9|7[178]9))\\d{5,6}|8[1-35-9]\\d{7,10}",,,,"812345678",,,[9,10,11,12]],[,,"177\\d{6,8}|800\\d{5,7}",,,,"8001234567",,,[8,9,10,11]],[,
43878			,"809\\d{7}",,,,"8091234567",,,[10]],[,,"804\\d{7}",,,,"8041234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ID",62,"0(?:0[1789]|10(?:00|1[67]))","0",,,"0",,,,[[,"(\\d{2})(\\d{5,8})","$1 $2",["2[124]|[36]1"],"(0$1)"],[,"(\\d{3})(\\d{5,8})","$1 $2",["[4579]|2[035-9]|[36][02-9]"],"(0$1)"],[,"(8\\d{2})(\\d{3,4})(\\d{3})","$1-$2-$3",["8[1-35-9]"],"0$1"],[,"(8\\d{2})(\\d{4})(\\d{4,5})","$1-$2-$3",["8[1-35-9]"],"0$1"],[,"(1)(500)(\\d{3})","$1 $2 $3",["15"],"$1"],[,"(177)(\\d{6,8})","$1 $2",["17"],"0$1"],
43879			[,"(800)(\\d{5,7})","$1 $2",["800"],"0$1"],[,"(804)(\\d{3})(\\d{4})","$1 $2 $3",["804"],"0$1"],[,"(80\\d)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4",["80[79]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,"8071\\d{6}",,,,"8071123456",,,[10]],[,,"1500\\d{3}|8071\\d{6}",,,,"8071123456",,,[7,10]],,,[,,,,,,,,,[-1]]],IE:[,[,,"[124-9]\\d{6,9}",,,,,,,[7,8,9,10],[5,6]],[,,"1\\d{7,8}|2(?:1\\d{6,7}|3\\d{7}|[24-9]\\d{5})|4(?:0[24]\\d{5}|[1-469]\\d{7}|5\\d{6}|7\\d{5}|8[0-46-9]\\d{7})|5(?:0[45]\\d{5}|1\\d{6}|[23679]\\d{7}|8\\d{5})|6(?:1\\d{6}|[237-9]\\d{5}|[4-6]\\d{7})|7[14]\\d{7}|9(?:1\\d{6}|[04]\\d{7}|[35-9]\\d{5})",
43880			,,,"2212345",,,,[5,6]],[,,"8(?:22\\d{6}|[35-9]\\d{7})",,,,"850123456",,,[9]],[,,"1800\\d{6}",,,,"1800123456",,,[10]],[,,"15(?:1[2-8]|[2-8]0|9[089])\\d{6}",,,,"1520123456",,,[10]],[,,"18[59]0\\d{6}",,,,"1850123456",,,[10]],[,,"700\\d{6}",,,,"700123456",,,[9]],[,,"76\\d{7}",,,,"761234567",,,[9]],"IE",353,"00","0",,,"0",,,,[[,"(1)(\\d{3,4})(\\d{4})","$1 $2 $3",["1"],"(0$1)"],[,"(\\d{2})(\\d{5})","$1 $2",["2[24-9]|47|58|6[237-9]|9[35-9]"],"(0$1)"],[,"(\\d{3})(\\d{5})","$1 $2",["40[24]|50[45]"],"(0$1)"],
43881			[,"(48)(\\d{4})(\\d{4})","$1 $2 $3",["48"],"(0$1)"],[,"(818)(\\d{3})(\\d{3})","$1 $2 $3",["81"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["[24-69]|7[14]"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["76|8[35-9]"],"0$1"],[,"(8\\d)(\\d)(\\d{3})(\\d{4})","$1 $2 $3 $4",["8[35-9]5"],"0$1"],[,"(700)(\\d{3})(\\d{3})","$1 $2 $3",["70"],"0$1"],[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3",["1(?:8[059]|5)","1(?:8[059]0|5)"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"18[59]0\\d{6}",,,,"1850123456",,,[10]],[,,"818\\d{6}",
43882			,,,"818123456",,,[9]],,,[,,"8[35-9]5\\d{7}",,,,"8551234567",,,[10]]],IL:[,[,,"1\\d{6,11}|[2-589]\\d{3}(?:\\d{3,6})?|6\\d{3}|7\\d{6,9}",,,,,,,[4,7,8,9,10,11,12]],[,,"(?:153\\d{1,2}|[2-489])\\d{7}",,,,"21234567",,,[8,11,12],[7]],[,,"5(?:[0-47-9]\\d{2}|5(?:01|2[23]|3[2-4]|4[45]|5[5689]|6[6-8]|7[0178]|8[6-9]|9[2-9])|6[2-9]\\d)\\d{5}",,,,"501234567",,,[9]],[,,"1(?:80[019]\\d{3}|255)\\d{3}",,,,"1800123456",,,[7,10]],[,,"1(?:212|(?:9(?:0[01]|19)|200)\\d{2})\\d{4}",,,,"1919123456",,,[8,9,10]],[,,"1700\\d{6}",
43883			,,,"1700123456",,,[10]],[,,,,,,,,,[-1]],[,,"7(?:18\\d|2[23]\\d|3[237]\\d|47\\d|6[58]\\d|7\\d{2}|8(?:2\\d|33|55|77|81)|9[2579]\\d)\\d{5}",,,,"771234567",,,[9]],"IL",972,"0(?:0|1[2-9])","0",,,"0",,,,[[,"([2-489])(\\d{3})(\\d{4})","$1-$2-$3",["[2-489]"],"0$1"],[,"([57]\\d)(\\d{3})(\\d{4})","$1-$2-$3",["[57]"],"0$1"],[,"(153)(\\d{1,2})(\\d{3})(\\d{4})","$1 $2 $3 $4",["153"],"$1"],[,"(1)([7-9]\\d{2})(\\d{3})(\\d{3})","$1-$2-$3-$4",["1[7-9]"],"$1"],[,"(1255)(\\d{3})","$1-$2",["125"],"$1"],[,"(1200)(\\d{3})(\\d{3})",
43884			"$1-$2-$3",["120"],"$1"],[,"(1212)(\\d{2})(\\d{2})","$1-$2-$3",["121"],"$1"],[,"(1599)(\\d{6})","$1-$2",["1599"],"$1"],[,"(151)(\\d{1,2})(\\d{3})(\\d{4})","$1-$2 $3-$4",["151"],"$1"],[,"(\\d{4})","*$1",["[2-689]"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"1700\\d{6}|[2-689]\\d{3}",,,,"1700123456",,,[4,10]],[,,"[2-689]\\d{3}|1599\\d{6}",,,,"1599123456",,,[4,10]],,,[,,"151\\d{8,9}",,,,"15112340000",,,[11,12]]],IM:[,[,,"[135789]\\d{6,9}",,,,,,,[10],[6]],[,,"1624[5-8]\\d{5}",,,,"1624756789",,,,[6]],[,,"7(?:4576|[59]24\\d|624[2-4])\\d{5}",
43885			,,,"7924123456"],[,,"808162\\d{4}",,,,"8081624567"],[,,"(?:872299|90[0167]624)\\d{4}",,,,"9016247890"],[,,"8(?:4(?:40[49]06|5624\\d)|70624\\d)\\d{3}",,,,"8456247890"],[,,"70\\d{8}",,,,"7012345678"],[,,"56\\d{8}",,,,"5612345678"],"IM",44,"00","0",,,"0",,,,,,[,,"7624[01689]\\d{5}",,,,"7624012345"],,,[,,,,,,,,,[-1]],[,,"3(?:08162\\d|3\\d{5}|4(?:40[49]06|5624\\d)|7(?:0624\\d|2299\\d))\\d{3}|55\\d{8}",,,,"5512345678"],,,[,,,,,,,,,[-1]]],IN:[,[,,"008\\d{9}|1\\d{7,12}|[2-9]\\d{9,10}",,,,,,,[8,9,10,11,12,
43886			13],[6,7]],[,,"(?:11|2[02]|33|4[04]|79)[2-7]\\d{7}|3880\\d{6}|80[2-467]\\d{7}|(?:1(?:2[0-249]|3[0-25]|4[145]|[59][14]|6[014]|7[1257]|8[01346])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[0-26-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[025]|[36][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91))[2-7]\\d{6}|(?:(?:1(?:2[35-8]|3[346-9]|4[236-9]|[59][0235-9]|6[235-9]|7[34689]|8[257-9])|2(?:1[134689]|3[24-8]|4[2-8]|5[25689]|6[2-4679]|7[13-79]|8[2-479]|9[235-9])|3(?:01|1[79]|2[1-5]|4[25-8]|5[125689]|6[235-7]|7[157-9]|8[2-467])|4(?:1[14578]|2[5689]|3[2-467]|5[4-7]|6[35]|73|8[2689]|9[2389])|5(?:[16][146-9]|2[14-8]|3[1346]|4[14-69]|5[46]|7[2-4]|8[2-8]|9[246])|6(?:1[1358]|2[2457]|3[2-4]|4[235-7]|[57][2-689]|6[24-578]|8[1-6])|8(?:1[1357-9]|2[235-8]|3[03-57-9]|4[0-24-9]|5\\d|6[2457-9]|7[1-6]|8[1256]|9[2-4]))\\d|7(?:(?:1[013-9]|2[0235-9]|3[2679]|4[1-35689]|5[2-46-9]|[67][02-9]|9\\d)\\d|8(?:2[0-6]|[013-8]\\d)))[2-7]\\d{5}",
43887			,,,"1123456789",,,[10],[6,7,8]],[,,"(?:600[1-3]\\d|7(?:0\\d{3}|19[0-5]\\d|2(?:[0235679]\\d{2}|[14][017-9]\\d|8(?:[0-59]\\d|[678][089]))|3(?:[05-8]\\d{2}|1(?:[089]\\d|11|7[5-8])|2(?:[0-49][089]|[5-8]\\d)|3[017-9]\\d|4(?:[07-9]\\d|11)|9(?:[016-9]\\d|[2-5][089]))|4(?:0\\d{2}|1(?:[015-9]\\d|[23][089]|4[089])|2(?:0[089]|[1-7][089]|[89]\\d)|3(?:[0-8][089]|9\\d)|4(?:[089]\\d|11|7[02-8])|[56]\\d[089]|7(?:[
43887089]\\d|11|7[02-8])|8(?:[0-24-7][089]|[389]\\d)|9(?:[0-6][089]|7[089]|[89]\\d))|5(?:[0346-8]\\d{2}|1(?:[07-9]\\d|11)|2(?:[04-9]\\d|[123][089])|5[017-9]\\d|9(?:[0-6][089]|[7-9]\\d))|6(?:0(?:[0-47]\\d|[5689][089])|(?:1[0-257-9]|[6-9]\\d)\\d|2(?:[0-4]\\d|[5-9][089])|3(?:[02-8][089]|[19]\\d)|4\\d[089]|5(?:[0-367][089]|[4589]\\d))|7(?:0(?:0[02-9]|[13-6][089]|[289]\\d|7[89])|[1-9]\\d{2})|8(?:[0-79]\\d{2}|8(?:[089]\\d|11|7[02-9]))|9(?:[089]\\d{2}|313|7(?:[02-8]\\d|9[07-9])))|8(?:0(?:[01589]\\d{2}|6[67]\\d|7(?:[02-8]\\d|9[05-9]))|1(?:[02-57-9]\\d{2}|1(?:[0-35-9]\\d|4[0-46-9])|6(?:[089]\\d|7[02-8]))|2(?:0(?:[089]\\d|7[02])|[14](?:[089]\\d|7[02-8])|[235-9]\\d{2})|3(?:[0357-9]\\d{2}|1(?:[089]\\d|7[02-6])|2(?:[09]\\d|77|8[0-689])|4(?:0[1-7]|[1-9]\\d)|6(?:[089]\\d|7[02-7]))|[45]\\d{3}|6(?:[02457-9]\\d{2}|1(?:[089]\\d|7[02-8])|3(?:[089]\\d|7[02-8])|6(?:[08]\\d|7[02-8]|9\\d))|7(?:0[07-9]\\d|[1-69]\\d{2}|[78](?:[089]\\d|7[02-8]))|8(?:[0-25-9]\\d{2}|3(?:[089]\\d|7[02-8])|4(?:[0489]\\d|7[02-68]))|9(?:[02-9]\\d{2}|1(?:[0289]\\d|7[2-6])))|9\\d{4})\\d{5}",
43888			,,,"8123456789",,,[10]],[,,"00800\\d{7}|1(?:600\\d{6}|80(?:0\\d{4,9}|3\\d{9}))",,,,"1800123456"],[,,"186[12]\\d{9}",,,,"1861123456789",,,[13]],[,,"1860\\d{7}",,,,"18603451234",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"IN",91,"00","0",,,"0",,,,[[,"(\\d{8})","$1",["561","5616","56161"],"$1",,1],[,"(\\d{5})(\\d{5})","$1 $2",["600|7(?:[02-8]|19|9[037-9])|8(?:0[015-9]|[1-9])|9","600|7(?:[078]|19[0-5]|2(?:[02356-9]|[14][017-9]|9[389])|3(?:[025-9]|1[017-9]|[34][017-9])|4(?:[0-35689]|[47][017-9])|5(?:[02346-9]|1[017-9]|5[017-9])|6(?:[02-9]|1[0-257-9])|9(?:[089]|31|7[02-9]))|8(?:0(?:[01589]|6[67]|7[02-9])|1(?:[0-57-9]|6[07-9])|2(?:0[07-9]|[14][07-9]|[235-9])|3(?:[03-57-9]|[126][07-9])|[45]|6(?:[02457-9]|[136][07-9])|7(?:[078][07-9]|[1-69])|8(?:[0-25-9]|3[07-9]|4[047-9])|9(?:[02-9]|1[027-9]))|9",
43889			"600|7(?:0|19[0-5]|2(?:[0235679]|[14][017-9]|8(?:[0-569]|[78][089])|9[389])|3(?:[05-8]|1(?:[0189]|7[5-9])|2(?:[5-8]|[0-49][089])|3[017-9]|4(?:[07-9]|11)|9(?:[01689]|[2345][089]|40|7[0189]))|4(?:[056]|1(?:[0135-9]|[23][089]|2[089]|4[089])|2(?:0[089]|[1-7][089]|[89])|3(?:[0-8][089]|9)|4(?:[089]|11|7[02-8])|7(?:[089]|11|7[02-8])|8(?:[0-24-7][089]|[389])|9(?:[0-7][089]|[89]))|5(?:[0346-9]|1[017-9]|2(?:[03-9]|[12][089])|5[017-9])|6(?:[0346-9]|1[0-257-9]|2(?:[0-4]\\d|[5-9][089])|5(?:[0-367][089]|[4589]))|7(?:0(?:[02-9]|1[089])|[1-9])|8(?:[0-79]|8(?:0[0189]|11|8[013-9]|9))|9(?:[089]|313|7(?:[02-8]|9[07-9])))|8(?:0(?:[01589]|6[67]|7(?:[02-8]|9[05-9]))|1(?:[02-57-9]|1(?:[0-35-9]|4[0-46-9])|6(?:[089]|7[02-8]))|2(?:0(?:[089]|7[02])|[14](?:[089]|7[02-8])|[235-9])|3(?:[0357-9]|1(?:[089]|7[02-6])|2(?:[09]|77|8[0-689])|4(?:0[1-7]|[1-9])|6(?:[089]|7[02-7]))|[45]|6(?:[02457-9]|1(?:[089]|7[02-8])|3(?:[089]|7[02-8])|6(?:[08]|7[02-8]|9\\d))|7(?:0[07-9]|[1-69]|7(?:[089]|7[02-8])|8(?:[089]|7[02-8]))|8(?:[0-25-9]|3(?:[089]|7[02-8])|4(?:[0489]|7[02-68]))|9(?:[02-9]|1(?:[0289]|7[2-6])))|9"],
43890			"0$1",,1],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["11|2[02]|33|4[04]|79[1-9]|80[2-46]"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1(?:2[0-249]|3[0-25]|4[145]|[59][14]|7[1257]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[0-26-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[025]|[36][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2-4]1|5[17]|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)"],
43891			"0$1",,1],[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3",["1(?:[23579]|[468][1-9])|[2-8]"],"0$1",,1],[,"(\\d{2})(\\d{3})(\\d{4})(\\d{3})","$1 $2 $3 $4",["008"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["140"],"$1",,1],[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2 $3",["160","1600"],"$1",,1],[,"(\\d{4})(\\d{4,5})","$1 $2",["180","1800"],"$1",,1],[,"(\\d{4})(\\d{2,4})(\\d{4})","$1 $2 $3",["180","1800"],"$1",,1],[,"(\\d{4})(\\d{3,4})(\\d{4})","$1 $2 $3",["186","1860"],"$1",,1],[,"(\\d{4})(\\d{3})(\\d{3})(\\d{3})",
43892			"$1 $2 $3 $4",["18[06]"],"$1",,1]],,[,,,,,,,,,[-1]],,,[,,"00800\\d{7}|1(?:600\\d{6}|8(?:0(?:0\\d{4,9}|3\\d{9})|6(?:0\\d{7}|[12]\\d{9})))",,,,"1800123456"],[,,"140\\d{7}",,,,"1409305260",,,[10]],,,[,,,,,,,,,[-1]]],IO:[,[,,"3\\d{6}",,,,,,,[7]],[,,"37\\d{5}",,,,"3709100"],[,,"38\\d{5}",,,,"3801234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"IO",246,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
43893		IQ:[,[,,"[1-7]\\d{7,9}",,,,,,,[8,9,10],[6,7]],[,,"1\\d{7}|(?:2[13-5]|3[02367]|4[023]|5[03]|6[026])\\d{6,7}",,,,"12345678",,,[8,9],[6,7]],[,,"7[3-9]\\d{8}",,,,"7912345678",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"IQ",964,"00","0",,,"0",,,,[[,"(1)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"0$1"],[,"([2-6]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[2-6]"],"0$1"],[,"(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
43894			,,[,,,,,,,,,[-1]]],IR:[,[,,"[1-8]\\d{5,9}|9(?:[0-4]\\d{8}|9\\d{8})",,,,,,,[6,7,10],[4,5,8]],[,,"(?:(?:1[137]|2[13-68]|3[1458]|4[145]|5[1468]|6[16]|7[1467]|8[13467])(?:\\d{8}|(?:[16]|[289]\\d?)\\d{3}))|94(?:000|11[1-7]|2\\d{2}|440)\\d{5}",,,,"2123456789",,,,[4,5,8]],[,,"9(?:0[1-3]\\d{2}|[1-3]\\d{3}|9(?:0\\d{2}|44\\d|810|9(?:00|11|9[89])))\\d{5}",,,,"9123456789",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:[2-6]0\\d|993)\\d{7}",,,,"9932123456",,,[10]],"IR",98,"00",
43895			"0",,,"0",,,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["[1-8]"],"0$1"],[,"(\\d{2})(\\d{4,5})","$1 $2",["[1-8]"],"0$1"],[,"(\\d{4,5})","$1",["96"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["9"],"0$1"]],,[,,"943\\d{7}",,,,"9432123456",,,[10]],,,[,,"(?:9411[1-7]|94440)\\d{5}",,,,"9411110000",,,[10]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],IS:[,[,,"[4-9]\\d{6}|38\\d{7}",,,,,,,[7,9]],[,,"(?:4(?:1[0-24-69]|2[0-7]|[37][0-8]|4[0-245]|5[0-68]|6\\d|8[0-36-8])|5(?:05|[156]\\d|2[02578]|3[0-79]|4[03-7]|7[0-2578]|8[0-35-9]|9[013-689])|87[23])\\d{4}",
43896			,,,"4101234",,,[7]],[,,"38[589]\\d{6}|(?:6(?:1[1-8]|2[0-6]|3[027-9]|4[014679]|5[0159]|[67][0-69]|9\\d)|7(?:5[057]|[6-8]\\d)|8(?:2[0-59]|3[0-4]|[469]\\d|5[1-9]|88))\\d{4}",,,,"6111234"],[,,"800\\d{4}",,,,"8001234",,,[7]],[,,"90\\d{5}",,,,"9011234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"49\\d{5}",,,,"4921234",,,[7]],"IS",354,"1(?:0(?:01|10|20)|100)|00",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1 $2",["[4-9]"]],[,"(3\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["3"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"809\\d{4}",
43897			,,,"8091234",,,[7]],,,[,,"(?:6(?:2[78]|49|8\\d)|8(?:7[0189]|80)|95[48])\\d{4}",,,,"6271234",,,[7]]],IT:[,[,,"[01589]\\d{5,10}|3(?:[12457-9]\\d{8}|[36]\\d{7,9})",,,,,,,[6,7,8,9,10,11]],[,,"0(?:[26]\\d{4,9}|(?:1(?:[0159]\\d|[27][1-5]|31|4[1-4]|6[1356]|8[2-57])|3(?:[0159]\\d|2[1-4]|3[12]|[48][1-6]|6[2-59]|7[1-7])|4(?:[0159]\\d|[23][1-9]|4[245]|6[1-5]|7[1-4]|81)|5(?:[0159]\\d|2[1-5]|3[2-6]|4[1-79]|6[4-6]|7[1-578]|8[3-8])|7(?:[0159]\\d|2[12]|3[1-7]|4[2346]|6[13569]|7[13-6]|8[1-59])|8(?:[0159]\\d|2[34578]|3[1-356]|[6-8][1-5])|9(?:[0159]\\d|[238][1-5]|4[12]|6[1-8]|7[1-6]))\\d{2,7})",
43898			,,,"0212345678"],[,,"3(?:[12457-9]\\d{8}|6\\d{7,8}|3\\d{7,9})",,,,"3123456789",,,[9,10,11]],[,,"80(?:0\\d{6}|3\\d{3})",,,,"800123456",,,[6,9]],[,,"0878\\d{5}|1(?:44|6[346])\\d{6}|89(?:2\\d{3}|4(?:[0-4]\\d{2}|[5-9]\\d{4}
43898)|5(?:[0-4]\\d{2}|[5-9]\\d{6})|9\\d{6})",,,,"899123456",,,[6,8,9,10]],[,,"84(?:[08]\\d{6}|[17]\\d{3})",,,,"848123456",,,[6,9]],[,,"1(?:78\\d|99)\\d{6}",,,,"1781234567",,,[9,10]],[,,"55\\d{8}",,,,"5512345678",,,[10]],"IT",39,"00",,,,,,,,[[,"(\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["0[26]|55"]],
43899			[,"(0[26])(\\d{4})(\\d{5})","$1 $2 $3",["0[26]"]],[,"(0[26])(\\d{4,6})","$1 $2",["0[26]"]],[,"(0\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["0[13-57-9][0159]"]],[,"(\\d{3})(\\d{3,6})","$1 $2",["0[13-57-9][0159]|8(?:03|4[17]|9[245])","0[13-57-9][0159]|8(?:03|4[17]|9(?:2|[45][0-4]))"]],[,"(0\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["0[13-57-9][2-46-8]"]],[,"(0\\d{3})(\\d{2,6})","$1 $2",["0[13-57-9][2-46-8]"]],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["[13]|8(?:00|4[08]|9[59])","[13]|8(?:00|4[08]|9(?:5[5-9]|9))"]],
43900			[,"(\\d{4})(\\d{4})","$1 $2",["894","894[5-9]"]],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["3"]]],,[,,,,,,,,,[-1]],1,,[,,"848\\d{6}",,,,"848123456",,,[9]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],JE:[,[,,"[135789]\\d{6,9}",,,,,,,[10],[6]],[,,"1534[0-24-8]\\d{5}",,,,"1534456789",,,,[6]],[,,"7(?:509\\d|7(?:00[378]|97[7-9])|829\\d|937\\d)\\d{5}",,,,"7797712345"],[,,"80(?:07(?:35|81)|8901)\\d{4}",,,,"8007354567"],[,,"(?:871206|90(?:066[59]|1810|71(?:07|55)))\\d{4}",,,,"9018105678"],[,,"8(?:4(?:4(?:4(?:05|42|69)|703)|5(?:041|800))|70002)\\d{4}",
43901			,,,"8447034567"],[,,"701511\\d{4}",,,,"7015115678"],[,,"56\\d{8}",,,,"5612345678"],"JE",44,"00","0",,,"0",,,,,,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}",,,,"7640123456"],,,[,,,,,,,,,[-1]],[,,"3(?:0(?:07(?:35|81)|8901)|3\\d{4}|4(?:4(?:4(?:05|42|69)|703)|5(?:041|800))|7(?:0002|1206))\\d{4}|55\\d{8}",,,,"5512345678"],,,[,,,,,,,,,[-1]]],JM:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"876(?:5(?:0[12]|1[0-468]|2[35]|63)|6(?:0[1-3579]|1[027-9]|[23]\\d|40|5[06]|6[2-589]|7[05]|8[04]|9[4-9])|7(?:0[2-689]|[1-6]\\d|8[056]|9[45])|9(?:0[1-8]|1[02378]|[2-8]\\d|9[2-468]))\\d{4}",
43902			,,,"8765123456",,,,[7]],[,,"876(?:2[14-9]\\d|[348]\\d{2}|5(?:0[3-9]|[2-57-9]\\d|6[0-24-9])|7(?:0[07]|7\\d|8[1-47-9]|9[0-36-9])|9(?:[01]9|9[0579]))\\d{4}",,,,"8762101234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"JM",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"876",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],JO:[,[,,"[235-9]\\d{7,8}",,,,,,,[8,
43903			9]],[,,"(?:2(?:6(?:2[0-35-9]|3[0-57-8]|4[24-7]|5[0-24-8]|[6-8][023]|9[0-3])|7(?:0[1-79]|10|2[014-7]|3[0-689]|4[019]|5[0-3578]))|32(?:0[1-69]|1[1-35-7]|2[024-7]|3\\d|4[0-3]|[57][023]|6[03])|53(?:0[0-3]|[13][023]|2[0-59]|49|5[0-35-9]|6[15]|7[45]|8[1-6]|9[0-36-9])|6(?:2[50]0|3(?:00|33)|4(?:0[0125]|1[2-7]|2[0569]|[38][07-9]|4[025689]|6[0-589]|7\\d|9[0-2])|5(?:[01][056]|2[034]|3[0-57-9]|4[17-8]|5[0-69]|6[0-35-9]|7[1-379]|8[0-68]|9[02-39]))|87(?:[02]0|7[08]|90))\\d{4}",,,,"62001234",,,[8]],[,,"7(?:55|7[025-9]|8[0-25-9]|9[0-25-9])\\d{6}",
43904			,,,"790123456",,,[9]],[,,"80\\d{6}",,,,"80012345",,,[8]],[,,"900\\d{5}",,,,"90012345",,,[8]],[,,"85\\d{6}",,,,"85012345",,,[8]],[,,"70\\d{7}",,,,"700123456",,,[9]],[,,,,,,,,,[-1]],"JO",962,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[2356]|87"],"(0$1)"],[,"(7)(\\d{4})(\\d{4})","$1 $2 $3",["7[457-9]"],"0$1"],[,"(\\d{2})(\\d{7})","$1 $2",["70"],"0$1"],[,"(\\d{3})(\\d{5,6})","$1 $2",["8[0158]|9"],"0$1"]],,[,,"74(?:66|77)\\d{5}",,,,"746612345",,,[9]],,,[,,,,,,,,,[-1]],[,,"8(?:10|8\\d)\\d{5}",
43905			,,,"88101234",,,[8]],,,[,,,,,,,,,[-1]]],JP:[,[,,"[1-9]\\d{8,9}|00(?:[36]\\d{7,14}|7\\d{5,7}|8\\d{7})",,,,,,,[8,9,10,11,12,13,14,15,16,17]],[,,"(?:1(?:1[235-8]|2[3-6]|3[3-9]|4[2-6]|[58][2-8]|6[2-7]|7[2-9]|9[1-9])|2[2-9]\\d|[36][1-9]\\d|4(?:6[02-8]|[2-578]\\d|9[2-59])|5(?:6[1-9]|7[2-8]|[2-589]\\d)|7(?:3[4-9]|4[02-9]|[25-9]\\d)|8(?:3[2-9]|4[5-9]|5[1-9]|8[03-9]|[2679]\\d)|9(?:[679][1-9]|[2-58]\\d))\\d{6}",,,,"312345678",,,[9]],[,,"[7-9]0[1-9]\\d{7}",,,,"9012345678",,,[10]],[,,"120\\d{6}|800\\d{7}|00(?:37\\d{6,13}|66\\d{6,13}|777(?:[01]\\d{2}|5\\d{3}|8\\d{4})|882[1245]\\d{4})",
43906			,,,"120123456"],[,,"990\\d{6}",,,,"990123456",,,[9]],[,,,,,,,,,[-1]],[,,"60\\d{7}",,,,"601234567",,,[9]],[,,"50[1-9]\\d{7}",,,,"5012345678",,,[10]],"JP",81,"010","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1-$2-$3",["(?:12|57|99)0"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["800"],"0$1"],[,"(\\d{4})(\\d{4})","$1-$2",["0077"],"$1"],[,"(\\d{4})(\\d{2})(\\d{3,4})","$1-$2-$3",["0077"],"$1"],[,"(\\d{4})(\\d{2})(\\d{4})","$1-$2-$3",["0088"],"$1"],[,"(\\d{4})(\\d{3})(\\d{3,4})","$1-$2-$3",["00(?:37|66)"],
43907			"$1"],[,"(\\d{4})(\\d{4})(\\d{4,5})","$1-$2-$3",["00(?:37|66)"],"$1"],[,"(\\d{4})(\\d{5})(\\d{5,6})","$1-$2-$3",["00(?:37|66)"],"$1"],[,"(\\d{4})(\\d{6})(\\d{6,7})","$1-$2-$3",["00(?:37|66)"],"$1"],[,"(\\d{2})(\\d{4})(\\d{4}
43907)","$1-$2-$3",["[2579]0|80[1-9]"],"0$1"],[,"(\\d{4})(\\d)(\\d{4})","$1-$2-$3",["1(?:26|3[79]|4[56]|5[4-68]|6[3-5])|5(?:76|97)|499|746|8(?:3[89]|63|47|51)|9(?:49|80|9[16])","1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:76|97)9|499[2468]|7468|8(?:3(?:8[78]|96)|636|477|51[24])|9(?:496|802|9(?:1[23]|69))",
43908			"1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:769|979[2-69])|499[2468]|7468|8(?:3(?:8[78]|96[2457-9])|636[2-57-9]|477|51[24])|9(?:496|802|9(?:1[23]|69))"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["1(?:2[3-6]|3[3-9]|4[2-6]|5[2-8]|[68][2-7]|7[2-689]|9[1-578])|2(?:2[03-689]|3[3-58]|4[0-468]|5[04-8]|6[013-8]|7[06-9]|8[02-57-9]|9[13])|4(?:2[28]|3[689]|6[035-7]|7[05689]|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9[4-9])|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9[014-9])|8(?:2[49]|3[3-8]|4[5-8]|5[2-9]|6[35-9]|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9[3-7])",
43909			"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9[2-8])|3(?:7[2-6]|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5[4-7]|6[2-9]|8[2-8]|9[236-9])|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3[34]|[4-7]))",
43910			"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6[56]))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))",
43911			"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6(?:5[25]|60)))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))"],
43912			"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["1|2(?:2[37]|5[5-9]|64|78|8[39]|91)|4(?:2[2689]|64|7[347])|5(?:[2-589]|39)|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93)","1|2(?:2[37]|5(?:[57]|[68]0|9[19])|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93[34])","1|2(?:2[37]|5(?:[57]|[68]0|9(?:17|99))|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93(?:31|4))"],
43913			"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["2(?:9[14-79]|74|[34]7|[56]9)|82|993"],"0$1"],[,"(\\d)(\\d{4})(\\d{4})","$1-$2-$3",["3|4(?:2[09]|7[01])|6[1-9]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[2479][1-9]"],"0$1"]],[[,"(\\d{3})(\\d{3})(\\d{3})","$1-$2-$3",["(?:12|57|99)0"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["800"],"0$1"],[,"(\\d{2})(\\d{4})(\\d{4}
43913)","$1-$2-$3",["[2579]0|80[1-9]"],"0$1"],[,"(\\d{4})(\\d)(\\d{4})","$1-$2-$3",["1(?:26|3[79]|4[56]|5[4-68]|6[3-5])|5(?:76|97)|499|746|8(?:3[89]|63|47|51)|9(?:49|80|9[16])",
43914			"1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:76|97)9|499[2468]|7468|8(?:3(?:8[78]|96)|636|477|51[24])|9(?:496|802|9(?:1[23]|69))","1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:769|979[2-69])|499[2468]|7468|8(?:3(?:8[78]|96[2457-9])|636[2-57-9]|477|51[24])|9(?:496|802|9(?:1[23]|69))"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["1(?:2[3-6]|3[3-9]|4[2-6]|5[2-8]|[68][2-7]|7[2-689]|9[1-578])|2(?:2[03-689]|3[3-58]|4[0-468]|5[04-8]|6[013-8]|7[06-9]|8[02-57-9]|9[13])|4(?:2[28]|3[689]|6[035-7]|7[05689]|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9[4-9])|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9[014-9])|8(?:2[49]|3[3-8]|4[5-8]|5[2-9]|6[35-9]|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9[3-7])",
43915			"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9[2-8])|3(?:7[2-6]|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5[4-7]|6[2-9]|8[2-8]|9[236-9])|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3[34]|[4-7]))",
43916			"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6[56]))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))",
43917			"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6(?:5[25]|60)))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))"],
43918			"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["1|2(?:2[37]|5[5-9]|64|78|8[39]|91)|4(?:2[2689]|64|7[347])|5(?:[2-589]|39)|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93)","1|2(?:2[37]|5(?:[57]|[68]0|9[19])|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93[34])","1|2(?:2[37]|5(?:[57]|[68]0|9(?:17|99))|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93(?:31|4))"],
43919			"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["2(?:9[14-79]|74|[34]7|[56]9)|82|993"],"0$1"],[,"(\\d)(\\d{4})(\\d{4})","$1-$2-$3",["3|4(?:2[09]|7[01])|6[1-9]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[2479][1-9]"],"0$1"]],[,,"20\\d{8}",,,,"2012345678",,,[10]],,,[,,"00(?:37\\d{6,13}|66\\d{6,13}|777(?:[01]\\d{2}|5\\d{3}|8\\d{4})|882[1245]\\d{4})",,,,"00777012"],[,,"570\\d{6}",,,,"570123456",,,[9]],,,[,,,,,,,,,[-1]]],KE:[,[,,"20\\d{6,7}|[4-9]\\d{6,9}",,,,,,,[7,8,9,10]],[,,"20\\d{6,7}|4(?:0\\d{6,7}|[136]\\d{7}|[245]\\d{5,7})|5(?:[08]\\d{7}|[1-79]\\d{5,7})|6(?:[01457-9]\\d{5,7}|2\\d{7}|6\\d{6,7})",
vendor: 7,382 bytes, lines 43920-43933
43920			,,,"202012345",,,[7,8,9]],[,,"7(?:[0-3679]\\d|4[0-46-9]|5[0-6]|8[0-25-9])\\d{6}",,,,"712123456",,,[9]],[,,"800[24-8]\\d{5,6}",,,,"800223456",,,[9,10]],[,,"900[02-9]\\d{5}",,,,"900223456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KE",254,"000","0",,,"005|0",,,,[[,"(\\d{2})(\\d{5,7})","$1 $2",["[24-6]"],"0$1"],[,"(\\d{3})(\\d{6})","$1 $2",["7"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["[89]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KG:[,[,
43921			,"[235-8]\\d{8,9}",,,,,,,[9,10],[5,6]],[,,"(?:3(?:1(?:[256]\\d|3[1-9]|47)|2(?:22|3[0-479]|6[0-7])|4(?:22|5[6-9]|6\\d)|5(?:22|3[4-7]|59|6\\d)|6(?:22|5[35-7]|6\\d)|7(?:22|3[468]|4[1-9]|59|[67]\\d)|9(?:22|4[1-8]|6\\d))|6(?:09|12|2[2-4])\\d)\\d{5}",,,,"312123456",,,[9],[5,6]],[,,"(?:20[0-35]|5[0-24-7]\\d|7[07]\\d)\\d{6}",,,,"700123456",,,[9]],[,,"800\\d{6,7}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KG",996,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",
43922			["[25-7]|31[25]"],"0$1"],[,"(\\d{4})(\\d{5})","$1 $2",["3(?:1[36]|[2-9])"],"0$1"],[,"(\\d{3})(\\d{3})(\\d)(\\d{3})","$1 $2 $3 $4",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KH:[,[,,"[1-9]\\d{7,9}",,,,,,,[8,9,10],[6,7]],[,,"(?:2[3-6]|3[2-6]|4[2-4]|[5-7][2-5])(?:[237-9]|4[56]|5\\d|6\\d?)\\d{5}|23(?:4[234]|8\\d{2})\\d{4}",,,,"23756789",,,[8,9],[6,7]],[,,"(?:1(?:[013-79]\\d|[28]\\d{1,2})|2[3-6]48|3(?:[18]\\d{2}|[2-6]48)|4[2-4]48|5[2-5]48|6(?:[016-9]\\d|[2-5]48)|7(?:[07-9]\\d|[16]\\d{2}|[2-5]48)|8(?:[013-79]\\d|8\\d{2})|9(?:6\\d{2}|7\\d{1,2}|[0-589]\\d))\\d{5}",
43923			,,,"91234567",,,[8,9]],[,,"1800(?:1\\d|2[019])\\d{4}",,,,"1800123456",,,[10]],[,,"1900(?:1\\d|2[09])\\d{4}",,,,"1900123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KH",855,"00[14-9]","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["1\\d[1-9]|[2-9]"],"0$1"],[,"(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3",["1[89]0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KI:[,[,,"[2458]\\d{4}|3\\d{4,7}|7\\d{7}",,,,,,,[5,8]],[,,"(?:[24]\\d|3[1-9]|50|8[0-5])\\d{3}|7(?:27|31|5[0-4])\\d{5}",
43924			,,,"31234"],[,,"7[23]0\\d{5}",,,,"72012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"30(?:0[01]\\d{2}|12(?:11|20))\\d{2}",,,,"30010000",,,[8]],"KI",686,"00",,,,"0",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KM:[,[,,"[3478]\\d{6}",,,,,,,[7]],[,,"7[4-7]\\d{5}",,,,"7712345"],[,,"[34]\\d{6}",,,,"3212345"],[,,,,,,,,,[-1]],[,,"(?:39[01]|8\\d{2})\\d{4}",,,,"8001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KM",269,"00",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})",
43925			"$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KN:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"869(?:2(?:29|36)|302|4(?:6[015-9]|70))\\d{4}",,,,"8692361234",,,,[7]],[,,"869(?:5(?:5[6-8]|6[5-7])|66\\d|76[02-7])\\d{4}",,,,"8697652917",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"KN",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],
43926			,"869",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KP:[,[,,"1\\d{9}|[28]\\d{7}",,,,,,,[8,10],[6,7]],[,,"2\\d{7}|85\\d{6}",,,,"21234567",,,[8],[6,7]],[,,"19[123]\\d{7}",,,,"1921234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KP",850,"00|99","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1"],"0$1"],[,"(\\d)(\\d{3})(\\d{4})","$1 $2 $3",["2"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,"2(?:[0-24-9]\\d{2}|3(?:[0-79]\\d|8[02-9]))\\d{4}",
43927			,,,"23821234",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KR:[,[,,"007\\d{9,11}|[1-7]\\d{3,9}|8\\d{8}",,,,,,,[4,5,6,8,9,10,12,13,14],[3,7]],[,,"(?:2|3[1-3]|[46][1-4]|5[1-5])(?:1\\d{2,3}|[1-9]\\d{6,7})",,,,"22123456",,,[4,5,6,8,9,10],[3,7]],[,,"1[0-26-9]\\d{7,8}",,,,"1000000000",,,[9,10]],[,,"(?:00798\\d{0,2}|80)\\d{7}",,,,"801234567",,,[9,12,13,14]],[,,"60[2-9]\\d{6}",,,,"602345678",,,[9]],[,,,,,,,,,[-1]],[,,"50\\d{8}",,,,"5012345678",,,[10]],[,,"70\\d{8}",,,,"7012345678",,,[10]],"KR",82,"00(?:[124-68]|3\\d{2}|7(?:[0-8]\\d|9[0-79]))",
43928			"0",,,"0(8[1-46-8]|85\\d{2})?",,,,[[,"(\\d{5})(\\d{3,4})(\\d{4})","$1 $2 $3",["00798"],"$1","0$CC-$1"],[,"(\\d{5})(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3 $4",["00798"],"$1","0$CC-$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3",["1(?:0|1[19]|[69]9|5[458])|[57]0","1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3",["1(?:[01]|5[1-4]|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]","1(?:[01]|5(?:[1-3]|4[56])|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d)(\\d{4})",
43929				"$1-$2-$3",["131","1312"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["131","131[13-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["13[2-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4",["30"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3",["2[1-9]"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})","$1-$2",["21[0-46-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})","$1-$2",["[3-6][1-9]1","[3-6][1-9]1(?:[0-46-9])"],"0$1","0$CC-$1"],[,"(\\d{4})(\\d{4})",
43930				"$1-$2",["1(?:5[246-9]|6[04678]|8[03579])","1(?:5(?:22|44|66|77|88|99)|6(?:00|44|6[16]|70|88)|8(?:00|33|55|77|99))"],"$1","0$CC-$1"]],[[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3",["1(?:0|1[19]|[69]9|5[458])|[57]0","1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3",["1(?:[01]|5[1-4]|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]","1(?:[01]|5(?:[1-3]|4[56])|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d)(\\d{4})","$1-$2-$3",["131","1312"],"0$1",
43931				"0$CC-$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["131","131[13-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["13[2-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4",["30"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3",["2[1-9]"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})","$1-$2",["21[0-46-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})","$1-$2",["[3-6][1-9]1","[3-6][1-9]1(?:[0-46-9])"],"0$1","0$CC-$1"],[,"(\\d{4})(\\d{4})","$1-$2",["1(?:5[246-9]|6[04678]|8[03579])",
43932				"1(?:5(?:22|44|66|77|88|99)|6(?:00|44|6[16]|70|88)|8(?:00|33|55|77|99))"],"$1","0$CC-$1"]],[,,"15\\d{7,8}",,,,"1523456789",,,[9,10]],,,[,,"00798\\d{7,9}",,,,"007981234567",,,[12,13,14]],[,,"1(?:5(?:22|44|66|77|88|99)|6(?:00|44|6[16]|70|88)|8(?:00|33|55|77|99))\\d{4}",,,,"15441234",,,[8]],,,[,,,,,,,,,[-1]]],KW:[,[,,"[12569]\\d{6,7}",,,,,,,[7,8]],[,,"(?:18\\d|2(?:[23]\\d{2}|4(?:[1-35-9]\\d|44)|5(?:0[034]|[2-46]\\d|5[1-3]|7[1-7])))\\d{4}",,,,"22345678"],[,,"(?:5(?:[05]\\d{2}|1[0-7]\\d|2(?:22|5[25])|6[56]\\d)|6(?:0[034679]\\d|222|5[015-9]\\d|6\\d{2}|7(?:0[013-9]|[67]\\d)|9(?:[069]\\d|3[039]))|9(?:0[09]\\d|22\\d|4[01479]\\d|55\\d|6[0679]\\d|7(?:02|[1-9]\\d)|8[057-9]\\d|9\\d{2}))\\d{4}",
43933			,,,"50012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KW",965,"00",,,,,,,,[[,"(\\d{4})(\\d{3,4})","$1 $2",["[16]|2(?:[0-35-9]|4[0-35-9])|9[024-9]|52[25]"]],[,"(\\d{3})(\\d{5})","$1 $2",["244|5(?:[015]|6[56])"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KY:[,[,,"[3589]\\d{9}
43933",,,,,,,[10],[7]],[,,"345(?:2(?:22|44)|444|6(?:23|38|40)|7(?:4[35-79]|6[6-9]|77)|8(?:00|1[45]|25|[48]8)|9(?:14|4[035-9]))\\d{4}",,,,"3452221234",,,,[7]],
43934			[,,"345(?:32[1-9]|5(?:1[67]|2[5-79]|4[6-9]|50|76)|649|9(?:1[67]|2[2-9]|3[689]))\\d{4}",,,,"3453231234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}|345976\\d{4}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"KY",1,"011","1",,,"1",,,,,,[,,"345849\\d{4}",,,,"3458491234"],,"345",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KZ:[,[,,"(?:33\\d|7\\d{2}|80[089])\\d{7}",,,,,,,[10]],[,,"33622\\d{5}|7(?:1(?:0(?:[23]\\d|4[0-3]|59|63)|1(?:[23]\\d|4[0-79]|59)|2(?:[23]\\d|59)|3(?:2\\d|3[0-79]|4[0-35-9]|59)|4(?:[24]\\d|3[013-9]|5[1-9])|5(?:2\\d|3[1-9]|4[0-7]|59)|6(?:[234]\\d|5[19]|61)|72\\d|8(?:[27]\\d|3[1-46-9]|4[0-5]))|2(?:1(?:[23]\\d|4[46-9]|5[3469])|2(?:2\\d|3[0679]|46|5[12679])|3(?:[234]\\d|5[139])|4(?:2\\d|3[1235-9]|59)|5(?:[23]\\d|4[01246-8]|59|61)|6(?:2\\d|3[1-9]|4[0-4]|59)|7(?:[2379]\\d|40|5[279])|8(?:[23]\\d|4[0-3]|59)|9(?:2\\d|3[124578]|59)))\\d{5}",
43935			,,,"7123456789"],[,,"7(?:0[012578]|47|6[02-4]|7[15-8]|85)\\d{7}",,,,"7710009998"],[,,"800\\d{7}",,,,"8001234567"],[,,"809\\d{7}",,,,"8091234567"],[,,,,,,,,,[-1]],[,,"808\\d{7}",,,,"8081234567"],[,,"751\\d{7}",,,,"7511234567"],"KZ",7,"810","8",,,"8",,"8~10",,,,[,,,,,,,,,[-1]],,,[,,"751\\d{7}",,,,"7511234567"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LA:[,[,,"[2-8]\\d{7,9}",,,,,,,[8,9,10],[6]],[,,"(?:2[13]|3(?:0\\d|[14])|[5-7][14]|41|8[1468])\\d{6}",,,,"21212862",,,[8,9],[6]],[,,"20(?:2[2389]|5[24-689]|7[6-8]|9[125-9])\\d{6}",
43936			,,,"2023123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LA",856,"00","0",,,"0",,,,[[,"(20)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4",["20"],"0$1"],[,"([2-8]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["2[13]|3[14]|[4-8]"],"0$1"],[,"(30)(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4",["30"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LB:[,[,,"[13-9]\\d{6,7}",,,,,,,[7,8]],[,,"(?:[14-6]\\d{2}|7(?:[2-57]\\d|62|8[0-7]|9[04-9])|8[02-9]\\d|9\\d{2})\\d{4}",
43937			,,,"1123456",,,[7]],[,,"(?:3\\d|7(?:[01]\\d|6[013-9]|8[89]|9[1-3])|81\\d)\\d{5}",,,,"71123456"],[,,,,,,,,,[-1]],[,,"9[01]\\d{6}",,,,"90123456",,,[8]],[,,"80\\d{6}",,,,"80123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LB",961,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[13-6]|7(?:[2-57]|62|8[0-7]|9[04-9])|8[02-9]|9"],"0$1"],[,"([7-9]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[89][01]|7(?:[01]|6[013-9]|8[89]|9[1-3])"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LC:[,
43938			[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"758(?:4(?:30|5[0-9]|6[2-9]|8[0-2])|57[0-2]|638)\\d{4}",,,,"7584305678",,,,[7]],[,,"758(?:28[4-7]|384|4(?:6[01]|8[4-9])|5(?:1[89]|20|84)|7(?:1[2-9]|2\\d|3[01]))\\d{4}",,,,"7582845678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"LC",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"758",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,
43939			[,,,,,,,,,[-1]]],LI:[,[,,"6\\d{8}|[23789]\\d{6}",,,,,,,[7,9]],[,,"(?:2(?:01|1[27]|3\\d|6[02-578]|96)|3(?:7[0135-7]|8[048]|9[0269]))\\d{4}",,,,"2345678",,,[7]],[,,"6(?:5(?:09|1\\d|20)|6(?:0[0-6]|10|2[06-9]|39))\\d{5}|7(?:[37-9]\\d|42|56)\\d{4}",,,,"660234567"],[,,"80(?:02[28]|9\\d{2})\\d{2}",,,,"8002222",,,[7]],[,,"90(?:02[258]|1(?:23|3[14])|66[136])\\d{2}",,,,"9002222",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LI",423,"00","0",,,"0|10(?:01|20|66)",,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",
43940			["[23789]"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["6[56]"]],[,"(69)(7\\d{2})(\\d{4})","$1 $2 $3",["697"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"870(?:28|87)\\d{2}",,,,"8702812",,,[7]],,,[,,"697(?:42|56|[78]\\d)\\d{4}",,,,"697861234",,,[9]]],LK:[,[,,"[1-9]\\d{8}",,,,,,,[9],[7]],[,,"1(?:1[2-57]\\d{6}|973\\d{5})|(?:2[13-7]|3[1-8]|4[157]|5[12457]|6[35-7]|[89]1)[2-57]\\d{6}",,,,"112345678",,,,[7]],[,,"7[0125-8]\\d{7}",,,,"712345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
43941			[,,,,,,,,,[-1]],"LK",94,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{1})(\\d{6})","$1 $2 $3",["[1-689]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LR:[,[,,"2\\d{7,8}|[378]\\d{8}|4\\d{6}|5\\d{6,8}",,,,,,,[7,8,9]],[,,"(?:2\\d{3}|33333)\\d{4}",,,,"21234567",,,[8,9]],[,,"(?:20\\d{2}|330\\d|4[67]|5(?:55)?\\d|77\\d{2}|88\\d{2})\\d{5}",,,,"770123456",,,[7,9]],[,,,,,,,,,[-1]],[,,"332(?:02|[2-5]\\d)\\d{4}",,,,"332021234",,,[9]],
43942			[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LR",231,"00","0",,,"0",,,,[[,"(2\\d)(\\d{3})(\\d{3})","$1 $2 $3",["2"],"0$1"],[,"([4-5])(\\d{3})(\\d{3})","$1 $2 $3",["[45]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[23578]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LS:[,[,,"[2568]\\d{7}",,,,,,,[8]],[,,"2\\d{7}",,,,"22123456"],[,,"[56]\\d{7}",,,,"50123456"],[,,"800[256]\\d{4}",,,,"80021234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
43943			"LS",266,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LT:[,[,,"[3-9]\\d{7}",,,,,,,[8]],[,,"(?:3[1478]|4[124-6]|52)\\d{6}",,,,"31234567"],[,,"6\\d{7}",,,,"61234567"],[,,"800\\d{5}",,,,"80012345"],[,,"9(?:0[0239]|10)\\d{5}",,,,"90012345"],[,,"808\\d{5}
43943",,,,"80812345"],[,,"700\\d{5}",,,,"70012345"],[,,,,,,,,,[-1]],"LT",370,"00","8",,,"[08]",,,,[[,"([34]\\d)(\\d{6})","$1 $2",["37|4(?:1|5[45]|6[2-4])"],"(8-$1)",,1],[,"([3-6]\\d{2})(\\d{5})",
43944			"$1 $2",["3[148]|4(?:[24]|6[09])|528|6"],"(8-$1)",,1],[,"([7-9]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["[7-9]"],"8 $1",,1],[,"(5)(2\\d{2})(\\d{4})","$1 $2 $3",["52[0-79]"],"(8-$1)",,1]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"70[67]\\d{5}",,,,"70712345"],,,[,,,,,,,,,[-1]]],LU:[,[,,"[24-9]\\d{3,10}|3(?:[0-46-9]\\d{2,9}|5[013-9]\\d{1,8})",,,,,,,[4,5,6,7,8,9,10,11]],[,,"(?:2[2-9]\\d{2,9}|(?:[3457]\\d{2}|8(?:0[2-9]|[13-9]\\d)|9(?:0[89]|[2-579]\\d))\\d{1,8})",,,,"27123456"],[,,"6[25-79][18]\\d{6}",,,,"628123456",
43945			,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"90[015]\\d{5}",,,,"90012345",,,[8]],[,,"801\\d{5}",,,,"80112345",,,[8]],[,,"70\\d{6}",,,,"70123456",,,[8]],[,,"20(?:1\\d{5}|[2-689]\\d{1,7})",,,,"20201234",,,[4,5,6,7,8,9,10]],"LU",352,"00",,,,"(15(?:0[06]|1[12]|35|4[04]|55|6[26]|77|88|99)\\d)",,,,[[,"(\\d{2})(\\d{3})","$1 $2",["[2-5]|7[1-9]|[89](?:[1-9]|0[2-9])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",["[2-5]|7[1-9]|[89](?:[1-9]|0[2-9])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",
43946			["20"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{1,2})","$1 $2 $3 $4",["2(?:[0367]|4[3-8])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4",["20"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{1,2})","$1 $2 $3 $4 $5",["2(?:[0367]|4[3-8])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{1,4})","$1 $2 $3 $4",["2(?:[12589]|4[12])|[3-5]|7[1-9]|8(?:[1-9]|0[2-9])|9(?:[1-9]|0[2-46-9])"],,"$CC $1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["70|80[01]|90[015]"],,"$CC $1"],[,"(\\d{3})(\\d{3})(\\d{3})",
43947			"$1 $2 $3",["6"],,"$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LV:[,[,,"[2689]\\d{7}",,,,,,,[8]],[,,"6\\d{7}",,,,"63123456"],[,,"2\\d{7}",,,,"21234567"],[,,"80\\d{6}",,,,"80123456"],[,,"90\\d{6}",,,,"90123456"],[,,"81\\d{6}",,,,"81123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LV",371,"00",,,,,,,,[[,"([2689]\\d)(\\d{3})(\\d{3})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LY:[,[,,"[25679]\\d{8}",,,,,,,[9],[7]],[,,"(?:2[1345]|5[1347]|6[123479]|71)\\d{7}",
43948			,,,"212345678",,,,[7]],[,,"9[1-6]\\d{7}",,,,"912345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LY",218,"00","0",,,"0",,,,[[,"([25679]\\d)(\\d{7})","$1-$2",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MA:[,[,,"[5-9]\\d{8}",,,,,,,[9]],[,,"5(?:2(?:[015-79]\\d|2[02-9]|3[2-57]|4[2-8]|8[235-7])\\d|3(?:[0-48]\\d|[57][2-9]|6[2-8]|9[3-9])\\d|4[067]\\d{2}|5[03]\\d{2})\\d{4}",,,,"520123456"],[,,"(?:6(?:[0-79]\\d|8[0-247-9])|7(?:[07][07]|6[12]))\\d{6}",
43949			,,,"650123456"],[,,"80\\d{7}",,,,"801234567"],[,,"89\\d{7}",,,,"891234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5924[01]\\d{4}",,,,"592401234"],"MA",212,"00","0",,,"0",,,,[[,"([5-7]\\d{2})(\\d{6})","$1-$2",["5(?:2[015-7]|3[0-4])|[67]"],"0$1"],[,"([58]\\d{3})(\\d{5})","$1-$2",["5(?:2[2-489]|3[5-9]|92)|892","5(?:2(?:[2-48]|9[0-7])|3(?:[5-79]|8[0-7])|924)|892"],"0$1"],[,"(5\\d{4})(\\d{4})","$1-$2",["5(?:29|38)","5(?:29|38)[89]"],"0$1"],[,"([5]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["5(?:4[067]|5[03])"],
43950			"0$1"],[,"(8[09])(\\d{7})","$1-$2",["8(?:0|9[013-9])"],"0$1"]],,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MC:[,[,,"[34689]\\d{7,8}",,,,,,,[8,9]],[,,"870\\d{5}|9[2-47-9]\\d{6}",,,,"99123456",,,[8]],[,,"3\\d{7}|4(?:4\\d|5[1-9])\\d{5}|6\\d{8}",,,,"612345678"],[,,"90\\d{6}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MC",377,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[39]"],"$1"],[,"(\\d{2})(\\d{3})(\\d{3})",
43951			"$1 $2 $3",["4"],"0$1"],[,"(6)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["6"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3",["8"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"870\\d{5}",,,,"87012345",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MD:[,[,,"[235-9]\\d{7}",,,,,,,[8]],[,,"(?:2[1-9]\\d|3[1-79]\\d|5(?:33|5[257]))\\d{5}",,,,"22212345"],[,,"(?:562|6\\d{2}|7(?:[189]\\d|6[07]|7[457-9]))\\d{5}",,,,"62112345"],[,,"800\\d{5}",,,,"80012345"],[,,"90[056]\\d{5}",,,,"90012345"],[,,"808\\d{5}
vendor: 12,523 bytes, lines 43951-43975
43951",,,,"80812345"],
43952			[,,,,,,,,,[-1]],[,,"3[08]\\d{6}",,,,"30123456"],"MD",373,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["22|3"],"0$1"],[,"([25-7]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["2[13-9]|[5-7]"],"0$1"],[,"([89]\\d{2})(\\d{5})","$1 $2",["[89]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"803\\d{5}",,,,"80312345"],,,[,,,,,,,,,[-1]]],ME:[,[,,"[2-9]\\d{7,8}",,,,,,,[8],[6]],[,,"(?:20[2-8]|3(?:0[2-7]|[12][235-7]|3[24-7])|4(?:0[2-467]|1[267])|5(?:0[2467]|1[267]|2[2367]))\\d{5}",,,,"30234567",,,,[6]],
43953			[,,"6(?:00\\d|3[024]\\d|6[0-25]\\d|[7-9]\\d{2})\\d{4}",,,,"67622901"],[,,"80[0-258]\\d{5}",,,,"80080002"],[,,"(?:9(?:4[1568]|5[178]))\\d{5}",,,,"94515151"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"78[1-49]\\d{5}",,,,"78108780"],"ME",382,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2-57-9]|6[036-9]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"77[1-9]\\d{5}",,,,"77273012"],,,[,,,,,,,,,[-1]]],MF:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"590(?:[02][79]|13|5[0-268]|[78]7)\\d{4}",,,,"590271234"],
43954			[,,"690(?:0[05-9]|[1-9]\\d)\\d{4}",,,,"690001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MF",590,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MG:[,[,,"[23]\\d{8}",,,,,,,[9],[7]],[,,"20(?:2\\d{2}|4[47]\\d|5[3467]\\d|6[279]\\d|7(?:2[29]|[35]\\d)|8[268]\\d|9[245]\\d)\\d{4}",,,,"202123456",,,,[7]],[,,"3[2-49]\\d{7}",,,,"321234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"22\\d{7}",,,,"221234567"],
43955			"MG",261,"00","0",,,"0",,,,[[,"([23]\\d)(\\d{2})(\\d{3})(\\d{2})","$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MH:[,[,,"[2-6]\\d{6}",,,,,,,[7]],[,,"(?:247|528|625)\\d{4}",,,,"2471234"],[,,"(?:235|329|45[56]|545)\\d{4}",,,,"2351234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"635\\d{4}",,,,"6351234"],"MH",692,"011","1",,,"1",,,,[[,"(\\d{3})(\\d{4})","$1-$2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
43956		MK:[,[,,"[2-578]\\d{7}",,,,,,,[8],[6,7]],[,,"(?:2(?:[23]\\d|5[124578]|6[01])|3(?:1[3-6]|[23][2-6]|4[2356])|4(?:[23][2-6]|4[3-6]|5[256]|6[25-8]|7[24-6]|8[4-6]))\\d{5}",,,,"22212345",,,,[6,7]],[,,"7(?:[0-25-8]\\d{2}|32\\d|421|9[23]\\d)\\d{4}",,,,"72345678"],[,,"800\\d{5}",,,,"80012345"],[,,"5[02-9]\\d{6}",,,,"50012345"],[,,"8(?:0[1-9]|[1-9]\\d)\\d{5}",,,,"80123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MK",389,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3",["2"],"0$1"],[,"([347]\\d)(\\d{3})(\\d{3})",
43957			"$1 $2 $3",["[347]"],"0$1"],[,"([58]\\d{2})(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4",["[58]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ML:[,[,,"[246-9]\\d{7}",,,,,,,[8]],[,,"(?:2(?:0(?:2\\d|7[0-8])|1(?:2[5-7]|[3-689]\\d))|44[1239]\\d)\\d{4}",,,,"20212345"],[,,"(?:2(?:079|17\\d)|[679]\\d{3}|8[239]\\d{2})\\d{4}",,,,"65012345"],[,,"80\\d{6}",,,,"80012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ML",223,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
43958			"$1 $2 $3 $4",["[246-9]"]],[,"(\\d{4})","$1",["67|74"]]],[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[246-9]"]]],[,,,,,,,,,[-1]],,,[,,"80\\d{6}",,,,"80012345"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MM:[,[,,"[178]\\d{5,7}|[24-6]\\d{5,8}|9(?:[279]\\d{0,2}|5|[34]\\d{1,2}|6(?:\\d{1,2})?|8(?:\\d{2})?)\\d{6}",,,,,,,[6,7,8,9,10],[5]],[,,"1(?:2\\d{1,2}|[35]\\d|4(?:\\d|2[236]|39)|6\\d?|[89][0-6]\\d)\\d{4}|2(?:2(?:000\\d{3}|\\d{4})|3\\d{4}|4(?:0\\d{5}|26\\d{4}|39\\d{4}|\\d{4})|5(?:1\\d{3,6}|[02-9]\\d{3,5})|[6-9]\\d{4})|4(?:2[245-8]|3(?:2(?:02)?|[346]|56?)|[46][2-6]|5[3-5])\\d{4}|5(?:2(?:2(?:\\d{1,2})?|[3-8])|3[2-68]|4(?:21?|[4-8])|5[23]|6[2-4]|7[2-8]|8[24-7]|9[2-7])\\d{4}|6(?:0[23]|1(?:2(?:0|4\\d)?|[356])|2[2-6]|3[24-6]|4(?:2(?:4\\d)?|[3-6])|5[2-4]|6[2-8]|7(?:[2367]|4(?:\\d|39)|5\\d?|8[145]\\d)|8[245]|9(?:20?|4))\\d{4}|7(?:[04][24-8]|1(?:20?|[3-7])|22|3[2-4]|5[2-7])\\d{4}|8(?:1(?:2\\d{1,2}|[3-689]\\d)|2(?:2\\d|3(?:\\d|20)|[4-8]\\d)|3[24]\\d|4[24-7]\\d|5[245]\\d|6[23]\\d)\\d{3}",
43959			,,,"1234567",,,[6,7,8,9],[5]],[,,"17[01]\\d{4}|9(?:2(?:[0-4]|5\\d{2}|6[0-5]\\d)|3(?:[0-36]|4[069])\\d|4(?:0[0-4]\\d|[1379]\\d|2\\d{2}|4[0-589]\\d|5\\d{2}|88)|5[0-6]|6(?:1\\d|9\\d{2}|\\d)|7(?:3\\d|[6-9]\\d{2})|8(?:\\d|9\\d{2})|9(?:1\\d|[5-7]\\d{2}|[089]))\\d{5}",,,,"92123456",,,[7,8,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"1333\\d{4}",,,,"13331234",,,[8]],"MM",95,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["1|2[245]"],"0$1"],[,"(2)(\\d{4})(\\d{4})",
43960			"$1 $2 $3",["251"],"0$1"],[,"(\\d)(\\d{2})(\\d{3})","$1 $2 $3",["16|2"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["432|67|81"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{3,4})","$1 $2 $3",["[4-8]"],"0$1"],[,"(9)(\\d{3})(\\d{4,6})","$1 $2 $3",["9(?:2[0-4]|[35-9]|4[137-9])"],"0$1"],[,"(9)([34]\\d{4})(\\d{4})","$1 $2 $3",["9(?:3[0-36]|4[0-57-9])"],"0$1"],[,"(9)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["92[56]"],"0$1"],[,"(9)(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3 $4",["93"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,
43961			,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MN:[,[,,"[12]\\d{7,9}|[57-9]\\d{7}",,,,,,,[8,9,10],[6,7]],[,,"[12](?:1\\d|2(?:[1-3]\\d?|7\\d)|3[2-8]\\d{1,2}|4[2-68]\\d{1,2}|5[1-4689]\\d{1,2})\\d{5}|5[0568]\\d{6}",,,,"50123456",,,,[6,7]],[,,"(?:8(?:[05689]\\d|3[01])|9[013-9]\\d)\\d{5}",,,,"88123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"7[05-8]\\d{6}",,,,"75123456",,,[8]],"MN",976,"001","0",,,"0",,,,[[,"([12]\\d)(\\d{2})(\\d{4})","$1 $2 $3",["[12]1"],"0$1"],[,"([12]2\\d)(\\d{5,6})",
43962			"$1 $2",["[12]2[1-3]"],"0$1"],[,"([12]\\d{3})(\\d{5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)2"],"0$1"],[,"(\\d{4})(\\d{4})","$1 $2",["[57-9]"],"$1"],[,"([12]\\d{4})(\\d{4,5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)[4-9]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MO:[,[,,"[268]\\d{7}",,,,,,,[8]],[,,"(?:28[2-57-9]|8[2-57-9]\\d)\\d{5}",,,,"28212345"],[,,"6(?:[2356]\\d|8[158])\\d{5}",,,,"66123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
43963			[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MO",853,"00",,,,,,,,[[,"([268]\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MP:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"670(?:2(?:3[3-7]|56|8[5-8])|32[1238]|4(?:33|8[348])|5(?:32|55|88)|6(?:64|70|82)|78[3589]|8[3-9]8|989)\\d{4}",,,,"6702345678",,,,[7]],[,,"670(?:2(?:3[3-7]|56|8[5-8])|32[1238]|4(?:33|8[348])|5(?:32|55|88)|6(?:64|70|82)|78[3589]|8[3-9]8|989)\\d{4}",,,,"6702345678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",
43964			,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"MP",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],,"670",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MQ:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"596(?:0[2-5]|[12]0|3[05-9]|4[024-8]|[5-7]\\d|89|9[4-8])\\d{4}",,,,"596301234"],[,,"696(?:[0-47-9]\\d|5[0-6]|6[0-4])\\d{4}",,,,"696201234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
43965			"MQ",596,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MR:[,[,,"[2-48]\\d{7}",,,,,,,[8]],[,,"25[08]\\d{5}|35\\d{6}|45[1-7]\\d{5}",,,,"35123456"],[,,"[234][0-46-9]\\d{6}",,,,"22123456"],[,,"800\\d{5}",,,,"80012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MR",222,"00",,,,,,,,[[,"([2-48]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,
43966			,,,,[-1]],,,[,,,,,,,,,[-1]]],MS:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"664491\\d{4}",,,,"6644912345",,,,[7]],[,,"66449[2-6]\\d{4}",,,,"6644923456",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"MS",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"664",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MT:[,[,,"[2357-9]\\d{7}",,,,,,,[8]],[,,"2(?:0(?:[169]\\d|3[1-4])|[1-357]\\d{2})\\d{4}",
43967			,,,"21001234"],[,,"(?:7(?:210|[79]\\d{2})|9(?:2(?:1[01]|31)|69[67]|8(?:1[1-3]|89|97)|9\\d{2}))\\d{4}",,,,"96961234"],[,,"800[3467]\\d{4}",,,,"80071234"],[,,"5(?:0(?:0(?:37|43)|6\\d{2}|70\\d|9[0168]\\d)|[12]\\d0[1-5])\\d{3}",,,,"50037123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3550\\d{4}",,,,"35501234"],"MT",356,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,"7117\\d{4}",,,,"71171234"],,,[,,,,,,,,,[-1]],[,,"501\\d{5}",,,,"50112345"],,,[,,,,,,,,,[-1]]],MU:[,[,,"[2-9]\\d{6,7}",,,,,,,[7,8]],[,,"(?:2(?:[03478]\\d|1[0-7]|6[1-69])|4(?:[013568]\\d|2[4-7])|5(?:44\\d|471)|6\\d{2}|8(?:14|3[129]))\\d{4}",
43968			,,,"2012345"],[,,"5(?:2[59]\\d|4(?:2[1-389]|4\\d|7[1-9]|9\\d)|7\\d{2}|8(?:[0-25689]\\d|4[3479]|7[15-8])|9[0-8]\\d)\\d{4}",,,,"52512345",,,[8]],[,,"80[012]\\d{4}",,,,"8001234",,,[7]],[,,"30\\d{5}",,,,"3012345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3(?:20|9\\d)\\d{4}",,,,"3201234",,,[7]],"MU",230,"0(?:0|[2-7]0|33)",,,,,,"020",,[[,"([2-46-9]\\d{2})(\\d{4})","$1 $2",["[2-46-9]"]],[,"(5\\d{3})(\\d{4})","$1 $2",["5"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MV:[,[,,"[346-8]\\d{6,9}|9(?:00\\d{7}|\\d{6})",
43969			,,,,,,[7,10]],[,,"(?:3(?:0[0-3]|3[0-59])|6(?:[57][02468]|6[024568]|8[024689]|90))\\d{4}",,,,"6701234",,,[7]],[,,"(?:46[46]|7[3-9]\\d|9[15-9]\\d)\\d{4}",,,,"7712345",,,[7]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MV",960,"0(?:0|19)",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1-$2",["[3467]|9(?:[1-9]|0[1-9])"]],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["[89]00"]]],,[,,"781\\d{4}",,,,"7812345",,,[7]],,,[,,,,,,,,,[-1]],[,,"4[05]0\\d{4}",
43970			,,,"4001234",,,[7]],,,[,,,,,,,,,[-1]]],MW:[,[,,"(?:1(?:\\d{2})?|[2789]\\d{2})\\d{6}",,,,,,,[7,9]],[,,"(?:1[2-9]|21\\d{2})\\d{5}",,,,"1234567"],[,,"(?:111|77\\d|88\\d|99\\d)\\d{6}",,,,"991234567",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MW",265,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["1"],"0$1"],[,"(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["2"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[1789]"],"0$1"]],,[,,,,,,,,,[-1]],
43971			,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MX:[,[,,"[1-9]\\d{9,10}",,,,,,,[10,11],[7,8]],[,,"(?:33|55|81)\\d{8}|(?:2(?:0[01]|2[1-9]|3[1-35-8]|4[13-9]|7[1-689]|8[1-578]|9[467])|3(?:1[1-79]|[2458][1-9]|7[1-8]|9[1-5])|4(?:1[1-57-9]|[24-6][1-9]|[37][1-8]|8[1-35-9]|9[2-689])|5(?:88|9[1-79])|6(?:1[2-68]|[234][1-9]|5[1-3689]|6[12457-9]|7[1-7]|8[67]|9[4-8])|7(?:[13467][1-9]|2[1-8]|5[13-9]|8[1-69]|9[17])|8(?:2[13-689]|3[1-6]|4[124-6]|6[1246-9]|7[1-378]|9[12479])|9(?:1[346-9]|2[1-4]|3[2-46-8]|5[1348]|[69][1-9]|7[12]|8[1-8]))\\d{7}",
43972			,,,"2221234567",,,[10],[7,8]],[,,"1(?:(?:33|55|81)\\d{8}|(?:2(?:2[1-9]|3[1-35-8]|4[13-9]|7[1-689]|8[1-578]|9[467])|3(?:1[1-79]|[2458][1-9]|7[1-8]|9[1-5])|4(?:1[1-57-9]|[24-6][1-9]|[37][1-8]|8[1-35-9]|9[2-689])|5(?:88|9[1-79])|6(?:1[2-68]|[2-4][1-9]|5[1-3689]|6[12457-9]|7[1-7]|8[67]|9[4-8])|7(?:[13467][1-9]|2[1-8]|5[13-9]|8[1-69]|9[17])|8(?:2[13-689]|3[1-6]|4[124-6]|6[1246-9]|7[1-378]|9[12479])|9(?:1[346-9]|2[1-4]|3[2-46-8]|5[1348]|[69][1-9]|7[12]|8[1-8]))\\d{7})",,,,"12221234567",,,[11]],[,,"8(?:00|88)\\d{7}",
43973			,,,"8001234567",,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,"300\\d{7}",,,,"3001234567",,,[10]],[,,"500\\d{7}",,,,"5001234567",,,[10]],[,,,,,,,,,[-1]],"MX",52,"0[09]","01",,,"0[12]|04[45](\\d{10})","1$1",,,[[,"([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["33|55|81"],"01 $1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["[2467]|3[0-2457-9]|5[089]|8[02-9]|9[0-35-9]"],"01 $1",,1],[,"(1)([358]\\d)(\\d{4})(\\d{4})","044 $2 $3 $4",["1(?:33|55|81)"],"$1",,1],[,"(1)(\\d{3})(\\d{3})(\\d{4})","044 $2 $3 $4",
43974			["1(?:[2467]|3[0-2457-9]|5[089]|8[2-9]|9[1-35-9])"],"$1",,1]],[[,"([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["33|55|81"],"01 $1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["[2467]|3[0-2457-9]|5[089]|8[02-9]|9[0-35-9]"],"01 $1",,1],[,"(1)([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3 $4",["1(?:33|55|81)"]],[,"(1)(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3 $4",["1(?:[2467]|3[0-2457-9]|5[089]|8[2-9]|9[1-35-9])"]]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MY:[,[,,"[13-9]\\d{7,9}",,,,,,,[8,9,
43975			10],[6,7]],[,,"(?:3[2-9]\\d|[4-9][2-9])\\d{6}",,,,"323456789",,,[8,9],[6,7]],[,,"1(?:1[1-6]\\d{2}
43975|[02-4679][2-9]\\d|59\\d{2}|8(?:1[23]|[2-9]\\d))\\d{5}",,,,"123456789",,,[9,10]],[,,"1[378]00\\d{6}",,,,"1300123456",,,[10]],[,,"1600\\d{6}",,,,"1600123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"154\\d{7}",,,,"1541234567",,,[10]],"MY",60,"00","0",,,"0",,,,[[,"([4-79])(\\d{3})(\\d{4})","$1-$2 $3",["[4-79]"],"0$1"],[,"(3)(\\d{4})(\\d{4})","$1-$2 $3",["3"],"0$1"],[,"([18]\\d)(\\d{3})(\\d{3,4})","$1-$2 $3",
43976			["1[02-46-9][1-9]|8"],"0$1"],[,"(1)([36-8]00)(\\d{2})(\\d{4})","$1-$2-$3-$4",["1[36-8]0"]],[,"(11)(\\d{4})(\\d{4})","$1-$2 $3",["11"],"0$1"],[,"(15[49])(\\d{3})(\\d{4})","$1-$2 $3",["15"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MZ:[,[,,"[28]\\d{7,8}",,,,,,,[8,9]],[,,"2(?:[1346]\\d|5[0-2]|[78][12]|93)\\d{5}",,,,"21123456",,,[8]],[,,"8[2-7]\\d{7}",,,,"821234567",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,
43977			,,[-1]],"MZ",258,"00",,,,,,,,[[,"([28]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["2|8[2-7]"]],[,"(80\\d)(\\d{3})(\\d{3})","$1 $2 $3",["80"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NA:[,[,,"[68]\\d{7,8}",,,,,,,[8,9]],[,,"6(?:1(?:17|2(?:[0189]\\d|[2-6]|7\\d?)|3(?:[01378]|2\\d)|4(?:[024]|10?|3[15]?)|69|7[014])|2(?:17|5(?:[0-36-8]|4\\d?)|69|70)|3(?:17|2(?:[0237]\\d?|[14-689])|34|6[289]|7[01]|81)|4(?:17|2(?:[012]|7\\d?)|4(?:[06]|1\\d?)|5(?:[01357]|[25]\\d?)|69|7[01])|5(?:17|2(?:[0459]|[23678]\\d?)|69|7[01])|6(?:17|2(?:5|6\\d?)|38|42|69|7[01])|7(?:17|2(?:[569]|[234]\\d?)|3(?:0\\d?|[13])|6[89]|7[01]))\\d{4}",
43978			,,,"61221234"],[,,"(?:60|8[125])\\d{7}",,,,"811234567",,,[9]],[,,,,,,,,,[-1]],[,,"8701\\d{5}",,,,"870123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"8(?:3\\d{2}|86)\\d{5}",,,,"88612345"],"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3",["8[1235]"],"0$1"],[,"(6\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["6"],"0$1"],[,"(88)(\\d{3})(\\d{3})","$1 $2 $3",["88"],"0$1"],[,"(870)(\\d{3})(\\d{3})","$1 $2 $3",["870"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
43979		NC:[,[,,"[2-57-9]\\d{5}",,,,,,,[6]],[,,"(?:2[03-9]|3[0-5]|4[1-7]|88)\\d{4}",,,,"201234"],[,,"(?:5[0-4]|[79]\\d|8[0-79])\\d{4}",,,,"751234"],[,,,,,,,,,[-1]],[,,"36\\d{4}",,,,"366711"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NC",687,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1.$2.$3",["[2-46-9]|5[0-4]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NE:[,[,,"[0289]\\d{7}",,,,,,,[8]],[,,"2(?:0(?:20|3[1-7]|4[134]|5[14]|6[14578]|7[1-578])|1(?:4[145]|5[14]|6[14-68]|7[169]|88))\\d{4}",
43980			,,,"20201234"],[,,"(?:8[089]|9\\d)\\d{6}",,,,"93123456"],[,,"08\\d{6}",,,,"08123456"],[,,"09\\d{6}",,,,"09123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NE",227,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[289]|09"]],[,"(08)(\\d{3})(\\d{3})","$1 $2 $3",["08"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NF:[,[,,"[13]\\d{5}",,,,,,,[6],[5]],[,,"(?:1(?:06|17|28|39)|3[012]\\d)\\d{3}",,,,"106609",,,,[5]],[,,"3[58]\\d{4}",,,,"381234",,,,[5]],[,
43981			,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NF",672,"00",,,,,,,,[[,"(\\d{2})(\\d{4})","$1 $2",["1"]],[,"(\\d)(\\d{5})","$1 $2",["3"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NG:[,[,,"[1-6]\\d{5,8}|9\\d{5,9}|[78]\\d{5,13}",,,,,,,[7,8,10,11,12,13,14],[5,6]],[,,"[12]\\d{6,7}|9(?:0[3-9]|[1-9]\\d)\\d{5}|(?:3\\d|4[023568]|5[02368]|6[02-469]|7[4-69]|8[2-9])\\d{6}|(?:4[47]|5[14579]|6[1578]|7[0-357])\\d{5,6}|(?:78|41)\\d{5}",,,,"12345678",,
43982			,[7,8],[5,6]],[,,"(?:1(?:7[34]\\d|8(?:04|[124579]\\d|8[0-3])|95\\d)|287[0-7]|3(?:18[1-8]|88[0-7]|9(?:8[5-9]|6[1-5]))|4(?:28[0-2]|6(?:7[1-9]|8[02-47])|88[0-2])|5(?:2(?:7[7-9]|8\\d)|38[1-79]|48[0-7]|68[4-7])|6(?:2(?:7[7-9]|8\\d)|4(?:3[7-9]|[68][129]|7[04-69]|9[1-8])|58[0-2]|98[7-9])|7(?:38[0-7]|69[1-8]|78[2-4])|8(?:28[3-9]|38[0-2]|4(?:2[12]|3[147-9]|5[346]|7[4-9]|8[014-689]|90)|58[1-8]|78[2-9]|88[5-7])|98[07]\\d)\\d{4}|(?:70(?:[1-689]\\d|7[0-3])|8(?:0(?:1[01]|[2-9]\\d)|1(?:[0-8]\\d|9[01]))|90[235-9]\\d)\\d{6}",
43983			,,,"8021234567",,,[8,10]],[,,"800\\d{7,11}",,,,"80017591759",,,[10,11,12,13,14]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NG",234,"009","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[12]|9(?:0[3-9]|[1-9])"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3",["[3-6]|7(?:[1-79]|0[1-9])|8[2-9]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["70|8[01]|90[235-9]"],"0$1"],[,"([78]00)(\\d{4})(\\d{4,5})","$1 $2 $3",["[78]00"],"0$1"],[,"([78]00)(\\d{5})(\\d{5,6})","$1 $2 $3",
43984			["[78]00"],"0$1"],[,"(78)(\\d{2})(\\d{3})","$1 $2 $3",["78"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"700\\d{7,11}",,,,"7001234567",,,[10,11,12,13,14]],,,[,,,,,,,,,[-1]]],NI:[,[,,"[125-8]\\d{7}",,,,,,,[8]],[,,"2\\d{7}",,,,"21234567"],[,,"(?:5(?:5[0-7]|[78]\\d)|6(?:20|3[035]|4[045]|5[05]|77|8[1-9]|9[059])|7[5-8]\\d|8\\d{2})\\d{5}",,,,"81234567"],[,,"1800\\d{4}",,,,"18001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NI",505,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],
43985			,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NL:[,[,,"1\\d{4,8}|[2-7]\\d{8}|[89]\\d{6,9}",,,,,,,[5,6,7,8,9,10]],[,,"(?:1[0135-8]|2[02-69]|3[0-68]|4[0135-9]|[57]\\d|8[478])\\d{7}",,,,"101234567",,,[9]],[,,"6[1-58]\\d{7}",,,,"612345678",,,[9]],[,,"800\\d{4,7}",,,,"8001234",,,[7,8,9,10]],[,,"90[069]\\d{4,7}",,,,"9061234",,,[7,8,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:6760|85\\d{2})\\d{5}",,,,"851234567",,,[9]],"NL",31,"00","0",,,"0",,,,[[,"([1-578]\\d)(\\d{3})(\\d{4})",
43986			"$1 $2 $3",["1[035]|2[0346]|3[03568]|4[0356]|5[0358]|7|8[4578]"],"0$1"],[,"([1-
439865]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["1[16-8]|2[259]|3[124]|4[17-9]|5[124679]"],"0$1"],[,"(6)(\\d{8})","$1 $2",["6[0-57-9]"],"0$1"],[,"(66)(\\d{7})","$1 $2",["66"],"0$1"],[,"(14)(\\d{3,4})","$1 $2",["14"],"$1"],[,"([89]0\\d)(\\d{4,7})","$1 $2",["80|9"],"0$1"]],,[,,"66\\d{7}",,,,"662345678",,,[9]],,,[,,"14\\d{3,4}",,,,"14123",,,[5,6]],[,,"140(?:1(?:[035]|[16-8]\\d)|2(?:[0346]|[259]\\d)|3(?:[03568]|[124]\\d)|4(?:[0356]|[17-9]\\d)|5(?:[0358]|[124679]\\d)|7\\d|8[458])",
43987			,,,"14020",,,[5,6]],,,[,,,,,,,,,[-1]]],NO:[,[,,"0\\d{4}|[2-9]\\d{7}",,,,,,,[5,8]],[,,"(?:2[1-4]|3[1-3578]|5[1-35-7]|6[1-4679]|7[0-8])\\d{6}",,,,"21234567",,,[8]],[,,"(?:4[015-8]|5[89]|87|9\\d)\\d{6}",,,,"40612345",,,[8]],[,,"80[01]\\d{5}",,,,"80012345",,,[8]],[,,"82[09]\\d{5}",,,,"82012345",,,[8]],[,,"810(?:0[0-6]|[2-8]\\d)\\d{3}",,,,"81021234",,,[8]],[,,"880\\d{5}",,,,"88012345",,,[8]],[,,"85[0-5]\\d{5}",,,,"85012345",,,[8]],"NO",47,"00",,,,,,,,[[,"([489]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["[489]"]],
43988			[,"([235-7]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[235-7]"]]],,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,"0\\d{4}|81(?:0(?:0[7-9]|1\\d)|5\\d{2})\\d{3}",,,,"01234"],,,[,,"81[23]\\d{5}",,,,"81212345",,,[8]]],NP:[,[,,"[1-8]\\d{7}|9(?:[1-69]\\d{6,8}|7[2-6]\\d{5,7}|8\\d{8})",,,,,,,[8,10],[6,7]],[,,"(?:1[0-6]\\d|2[13-79][2-6]|3[135-8][2-6]|4[146-9][2-6]|5[135-7][2-6]|6[13-9][2-6]|7[15-9][2-6]|8[1-46-9][2-6]|9[1-79][2-6])\\d{5}",,,,"14567890",,,[8],[6,7]],[,,"9(?:6[013]|7[245]|8[0-24-6])\\d{7}",,,,"9841234567",
43989			,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NP",977,"00","0",,,"0",,,,[[,"(1)(\\d{7})","$1-$2",["1[2-6]"],"0$1"],[,"(\\d{2})(\\d{6})","$1-$2",["1[01]|[2-8]|9(?:[1-69]|7[15-9])"],"0$1"],[,"(9\\d{2})(\\d{7})","$1-$2",["9(?:6[013]|7[245]|8)"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NR:[,[,,"[458]\\d{6}",,,,,,,[7]],[,,"(?:444|888)\\d{4}",,,,"4441234"],[,,"55[5-9]\\d{4}",,,,"5551234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,
43990			,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NR",674,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NU:[,[,,"[1-5]\\d{3}",,,,,,,[4]],[,,"[34]\\d{3}",,,,"4002"],[,,"[125]\\d{3}",,,,"1234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NU",683,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NZ:[,[,,"6[235-9]\\d{6}|[2-57-9]\\d{7,9}",,,,,,,[8,9,10],[7]],[,,"(?:3[2-79]|[49][2-9]|6[235-9]|7[2-57-9])\\d{6}|24099\\d{3}",
43991			,,,"32345678",,,[8],[7]],[,,"2(?:[028]\\d{7,8}|1(?:[03]\\d{5,7}|[12457]\\d{5,6}|[689]\\d{5})|[79]\\d{7})",,,,"211234567"],[,,"508\\d{6,7}|80\\d{6,8}",,,,"800123456"],[,,"90\\d{6,7}",,,,"900123456",,,[8,9]],[,,,,,,,,,[-1]],[,,"70\\d{7}",,,,"701234567",,,[9]],[,,,,,,,,,[-1]],"NZ",64,"0(?:0|161)","0",,,"0",,"00",,[[,"(\\d)(\\d{3})(\\d{4})","$1-$2 $3",["240|[346]|7[2-57-9]|9[1-9]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["21"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3,5})","$1 $2 $3",["2(?:1[1-9]|[69]|7[0-35-9])|70|86"],
43992			"0$1"],[,"(2\\d)(\\d{3,4})(\\d{4})","$1 $2 $3",["2[028]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["90"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["2(?:10|74)|5|[89]0"],"0$1"]],,[,,"[28]6\\d{6,7}",,,,"26123456",,,[8,9]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],OM:[,[,,"(?:5|[279]\\d)\\d{6}|800\\d{5,6}",,,,,,,[7,8,9]],[,,"2[2-6]\\d{6}",,,,"23123456",,,[8]],[,,"7[19]\\d{6}|9(?:0[1-9]|[1-9]\\d)\\d{5}",,,,"92123456",,,[8]],[,,"8007\\d{4,5}|500\\d{4}",,,,"80071234"],[,,"900\\d{5}",
43993			,,,"90012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"OM",968,"00",,,,,,,,[[,"(2\\d)(\\d{6})","$1 $2",["2"]],[,"([79]\\d{3})(\\d{4})","$1 $2",["[79]"]],[,"([58]00)(\\d{4,6})","$1 $2",["[58]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PA:[,[,,"[1-9]\\d{6,7}",,,,,,,[7,8]],[,,"(?:1(?:0[0-8]|1[49]|2[37]|3[0137]|4[147]|5[05]|6[58]|7[0167]|8[58]|9[139])|2(?:[0235679]\\d|1[0-7]|4[04-9]|8[028])|3(?:[09]\\d|1[014-7]|2[0-3]|3[03]|4[03-57]|55|6[068]|7[06-8]|8[06-9])|4(?:3[013-69]|4\\d|7[0-589])|5(?:[
4399301]\\d|2[0-7]|[56]0|79)|7(?:0[09]|2[0-267]|3[06]|[469]0|5[06-9]|7[0-24-79]|8[7-9])|8(?:09|[34]\\d|5[0134]|8[02])|9(?:0[6-9]|1[016-8]|2[036-8]|3[3679]|40|5[0489]|6[06-9]|7[046-9]|8[36-8]|9[1-9]))\\d{4}",
43994			,,,"2001234",,,[7]],[,,"(?:1[16]1|21[89]|8(?:1[01]|7[23]))\\d{4}|6(?:[024-9]\\d|1[0-5]|3[0-24-9])\\d{5}",,,,"60012345"],[,,"80[09]\\d{4}",,,,"8001234",,,[7]],[,,"(?:779|8(?:55|60|7[78])|9(?:00|81))\\d{4}",,,,"8601234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PA",507,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1-$2",["[1-57-9]"]],[,"(\\d{4})(\\d{4})","$1-$2",["6"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PE:[,[,,"[14-9]\\d{7,8}",,,,,,,[8,9],[6,7]],[,,"(?:1\\d|4[1-4]|5[1-46]|6[1-7]|7[2-46]|8[2-4])\\d{6}",
43995			,,,"11234567",,,[8],[6,7]],[,,"9\\d{8}",,,,"912345678",,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"805\\d{5}",,,,"80512345",,,[8]],[,,"801\\d{5}",,,,"80112345",,,[8]],[,,"80[24]\\d{5}",,,,"80212345",,,[8]],[,,,,,,,,,[-1]],"PE",51,"19(?:1[124]|77|90)00","0"," Anexo ",,"0",,,,[[,"(1)(\\d{7})","$1 $2",["1"],"(0$1)"],[,"([4-8]\\d)(\\d{6})","$1 $2",["[4-7]|8[2-4]"],"(0$1)"],[,"(\\d{3})(\\d{5})","$1 $2",["80"],"(0$1)"],[,"(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["9"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,
43996			,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PF:[,[,,"4\\d{5,7}|8\\d{7}",,,,,,,[6,8]],[,,"4(?:[09][45689]\\d|4)\\d{4}",,,,"40412345"],[,,"8[79]\\d{6}",,,,"87123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PF",689,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["4[09]|8[79]"]],[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",["44"]]],,[,,,,,,,,,[-1]],,,[,,"44\\d{4}",,,,"441234",,,[6]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PG:[,[,,"[1-9]\\d{6,7}",,
43997			,,,,,[7,8]],[,,"(?:3[0-2]\\d|4[257]\\d|5[34]\\d|64[1-9]|77(?:[0-24]\\d|30)|85[02-46-9]|9[78]\\d)\\d{4}",,,,"3123456",,,[7]],[,,"7(?:[0-689]\\d|75)\\d{5}",,,,"70123456",,,[8]],[,,"180\\d{4}",,,,"1801234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"2(?:0[0-47]|7[568])\\d{4}",,,,"2751234",,,[7]],"PG",675,"140[1-3]|00",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1 $2",["[13-689]|27"]],[,"(\\d{4})(\\d{4})","$1 $2",["20|7"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PH:[,
43998			[,,"2\\d{5,7}|[3-9]\\d{7,9}|1800\\d{7,9}",,,,,,,[6,8,9,10,11,12,13],[5,7]],[,,"2\\d{5}(?:\\d{2})?|(?:3[2-68]|4[2-9]|5[2-6]|6[2-58]|7[24578]|8[2-8])\\d{7}|88(?:22\\d{6}|42\\d{4})",,,,"21234567",,,[6,8,9,10],[5,7]],[,,"(?:81[37]|9(?:0[5-9]|1[024-9]|2[0-35-9]|3[02-9]|4[235-9]|5[056]|6[5-7]|7[34-79]|89|9[4-9]))\\d{7}",,,,"9051234567",,,[10]],[,,"1800\\d{7,9}",,,,"180012345678",,,[11,12,13]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PH",63,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})",
43999				"$1 $2 $3",["2"],"(0$1)"],[,"(2)(\\d{5})","$1 $2",["2"],"(0$1)"],[,"(\\d{4})(\\d{4,6})","$1 $2",["3(?:23|39|46)|4(?:2[3-6]|[35]9|4[26]|76)|5(?:22|44)|642|8(?:62|8[245])","3(?:230|397|461)|4(?:2(?:35|[46]4|51)|396|4(?:22|63)|59[347]|76[15])|5(?:221|446)|642[23]|8(?:622|8(?:[24]2|5[13]))"],"(0$1)"],[,"(\\d{5})(\\d{4})","$1 $2",["346|4(?:27|9[35])|883","3469|4(?:279|9(?:30|56))|8834"],"(0$1)"],[,"([3-8]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[3-8]"],"(0$1)"],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["81|9"],
44000				"0$1"],[,"(1800)(\\d{3})(\\d{4})","$1 $2 $3",["1"]],[,"(1800)(\\d{1,2})(\\d{3})(\\d{4})","$1 $2 $3 $4",["1"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PK:[,[,,"1\\d{8}|[2-8]\\d{5,11}|9(?:[013-9]\\d{4,9}|2\\d(?:111\\d{6}|\\d{3,7}))",,,,,,,[8,9,10,11,12],[6,7]],[,,"(?:21|42)[2-9]\\d{7}|(?:2[25]|4[0146-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)[2-9]\\d{6}|(?:2(?:3[2358]|4[2-4]|9[2-8])|45[3479]|54[2-467]|60[468]|72[236]|8(?:2[2-689]|3[23578]|4[3478]|5[2356])|9(?:2[2-8]|3[27-9]|4[2-6]|6[3569]|9[25-8]))[2-9]\\d{5,6}|58[126]\\d{7}",
44001			,,,"2123456789",,,[9,10],[6,7,8]],[,,"3(?:[014]\\d|2[0-5]|3[0-7]|55|64)\\d{7}",,,,"3012345678",,,[10]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"900\\d{5}",,,,"90012345",,,[8]],[,,,,,,,,,[-1]],[,,"122\\d{6}",,,,"122044444",,,[9]],[,,,,,,,,,[-1]],"PK",92,"00","0",,,"0",,,,[[,"(\\d{2})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4",["(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)1","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)11","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)111"],"(0$1)"],
44002			[,"(\\d{3})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4",["2[349]|45|54|60|72|8[2-5]|9[2-9]","(?:2[349]|45|54|60|72|8[2-5]|9[2-9])\\d1","(?:2[349]|45|54|60|72|8[2-5]|9[2-9])\\d11","(?:2[349]|45|54|60|72|8[2-5]|9[2-9])\\d111"],"(0$1)"],[,"(\\d{2})(\\d{7,8})","$1 $2",["(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)[2-9]"],"(0$1)"],[,"(\\d{3})(\\d{6,7})","$1 $2",["2[349]|45|5(?:4|8[12])|60|72|8[2-5]|9[2-9]","(?:2[349]|45|5(?:4|8[12])|60|72|8[2-5]|9[2-9])\\d[2-9]"],"(0$1)"],[,"(3\\d{2})(\\d{7})","$1 $2",
44003				["3"],"0$1"],[,"(1\\d{3})(\\d{5,6})","$1 $2",["1"],"$1"],[,"(586\\d{2})(\\d{5})","$1 $2",["586"],"(0$1)"],[,"([89]00)(\\d{3})(\\d{2})","$1 $2 $3",["[89]00"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"(?:2(?:[125]|3[2358]|4[2-4]|9[2-8])|4(?:[0-246-9]|5[3479])|5(?:[1-35-7]|4[2-467])|6(?:[1-8]|0[468])|7(?:[14]|2[236])|8(?:[16]|2[2-689]|3[23578]|4[3478]|5[2356])|9(?:1|22|3[27-9]|4[2-6]|6[3569]|9[2-7]))111\\d{6}",,,,"21111825888",,,[11,12]],,,[,,,,,,,,,[-1]]],PL:[,[,,"[1-57-9]\\d{6,8}|6\\d{5,8}",,
44004			,,,,,[6,7,8,9]],[,,"(?:1[2-8]|2[2-69]|3[2-4]|4[1-468]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145])(?:\\d{7}|19\\d{3})",,,,"123456789",,,[7,9]],[,,"(?:45|5[0137]|6[069]|7[2389]|88)\\d{7}",,,,"512345678",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"70[01346-8]\\d{6}",,,,"701234567",,,[9]],[,,"801\\d{6}",,,,"801234567",,,[9]],[,,,,,,,,,[-1]],[,,"39\\d{7}",,,,"391234567",,,[9]],"PL",48,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1 $2",["11[68]|64"]],[,"(\\d{5})","$1",["19"]],[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",
44005			["1[2-8]|2[2-69]|3[2-4]|4[1-468]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145]"]],[,"(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3",["64"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["26|39|45|5[0137]|6[0469]|7[02389]|8[08]"]],[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2}
44005)","$1 $2 $3 $4",["[14]|2[0-57-9]|3[2-4]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145]"]]],,[,,"64\\d{4,7}",,,,"641234567"],,,[,,,,,,,,,[-1]],[,,"804\\d{6}",,,,"804123456",,,[9]],,,[,,,,,,,,,[-1]]],PM:[,[,,"[45]\\d{5}",,,,,,,[6]],[,,"41\\d{4}",,,,"411234"],
44006			[,,"(?:40|55)\\d{4}",,,,"551234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PM",508,"00","0",,,"0",,,,[[,"([45]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PR:[,[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"(?:787|939)[2-9]\\d{6}",,,,"7872345678",,,,[7]],[,,"(?:787|939)[2-9]\\d{6}",,,,"7872345678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],
44007			[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"PR",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],,"787|939",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PS:[,[,,"1\\d{9}|[24589]\\d{7,8}",,,,,,,[8,9,10],[7]],[,,"(?:22[234789]|42[45]|82[01458]|92[369])\\d{5}",,,,"22234567",,,[8],[7]],[,,"5[69]\\d{7}",,,,"599123456",,,[9]],[,,"1800\\d{6}",,,,"1800123456",,,[10]],[,,,,,,,,,[-1]],[,,"1700\\d{6}",,,,"1700123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PS",970,
44008			"00","0",,,"0",,,,[[,"([2489])(2\\d{2})(\\d{4})","$1 $2 $3",["[2489]"],"0$1"],[,"(5[69]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["5"],"0$1"],[,"(1[78]00)(\\d{3})(\\d{3})","$1 $2 $3",["1"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PT:[,[,,"[2-46-9]\\d{8}",,,,,,,[9]],[,,"2(?:[12]\\d|[35][1-689]|4[1-59]|6[1-35689]|7[1-9]|8[1-69]|9[1256])\\d{6}",,,,"212345678"],[,,"9(?:[1236]\\d{2}|480)\\d{5}",,,,"912345678"],[,,"80[02]\\d{6}",,,,"800123456"],[,,"6(?:0[178]|4[68])\\d{6}|76(?:0[1-57]|1[2-47]|2[237])\\d{5}",
44009			,,,"760123456"],[,,"80(?:8\\d|9[1579])\\d{5}",,,,"808123456"],[,,"884[0-4689]\\d{5}",,,,"884123456"],[,,"30\\d{7}",,,,"301234567"],"PT",351,"00",,,,,,,,[[,"(2\\d)(\\d{3})(\\d{4})","$1 $2 $3",["2[12]"]],[,"([2-46-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["2[3-9]|[346-9]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"7(?:0(?:7\\d|8[17]))\\d{5}",,,,"707123456"],,,[,,"600\\d{6}",,,,"600110000"]],PW:[,[,,"[2-8]\\d{6}",,,,,,,[7]],[,,"2552255|(?:277|345|488|5(?:35|44|87)|6(?:22|54|79)|7(?:33|47)|8(?:24|55|76))\\d{4}",
44010			,,,"2771234"],[,,"(?:6[234689]0|77[45789])\\d{4}",,,,"6201234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PW",680,"01[12]",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PY:[,[,,"5[0-5]\\d{4,7}|[2-46-9]\\d{5,8}",,,,,,,[6,7,8,9],[5]],[,,"(?:[26]1|3[289]|4[124678]|7[123]|8[1236])\\d{5,7}|(?:2(?:2[4568]|7[15]|9[1-5])|3(?:18|3[167]|4[2357]|51)|4(?:18|2[45]|3[12]|5[13]|64|71|9[1-47])|5(?:[1-4]\\d|5[0234])|6(?:3[1-3]|44|7[1-4678])|7(?:17|4[0-4]|6[1-578]|75|8[0-8])|858)\\d{5,6}",
44011			,,,"212345678",,,[7,8,9],[5,6]],[,,"9(?:6[12]|[78][1-6]|9[1-5])\\d{6}",,,,"961456789",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"8700[0-4]\\d{4}",,,,"870012345",,,[9]],"PY",595,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{5})","$1 $2",["(?:[26]1|3[289]|4[124678]|7[123]|8[1236])"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["(?:[26]1|3[289]|4[124678]|7[123]|8[1236])"],"(0$1)"],[,"(\\d{3})(\\d{3,6})","$1 $2",["[2-9]0"],"0$1"],[,"(\\d{3})(\\d{6})","$1 $2",["9[1-9]"],"0$1"],
44012			[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["8700"]],[,"(\\d{3})(\\d{4,5})","$1 $2",["[2-8][1-9]"],"(0$1)"],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[2-8][1-9]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"[2-9]0\\d{4,7}",,,,"201234567"],,,[,,,,,,,,,[-1]]],QA:[,[,,"[2-8]\\d{6,7}",,,,,,,[7,8]],[,,"4[04]\\d{6}",,,,"44123456",,,[8]],[,,"[3567]\\d{7}",,,,"33123456",,,[8]],[,,"800\\d{4}",,,,"8001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"QA",974,"00",,,,,,,,[[,"([28]\\d{2})(\\d{4})",
44013			"$1 $2",["[28]"]],[,"([3-7]\\d{3})(\\d{4})","$1 $2",["[3-7]"]]],,[,,"2(?:[12]\\d|61)\\d{4}",,,,"2123456",,,[7]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],RE:[,[,,"[268]\\d{8}",,,,,,,[9]],[,,"262\\d{6}",,,,"262161234"],[,,"69(?:2\\d{2}|3(?:0[0-46]|1[013]|2[0-2]|3[039]|4[0-7]|5[05]|6[06]|7[07]|8[0-38]|9[0-479]))\\d{4}",,,,"692123456"],[,,"80\\d{7}",,,,"801234567"],[,,"89[1-37-9]\\d{6}",,,,"891123456"],[,,"8(?:1[019]|2[0156]|84|90)\\d{6}",,,,"810123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"RE",
44014			262,"00","0",,,"0",,,,[[,"([268]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],1,"262|69|8",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],RO:[,[,,"[23]\\d{5,8}|[7-9]\\d{8}",,,,,,,[6,9]],[,,"2(?:1(?:\\d{7}|9\\d{3}
44014)|[3-6](?:\\d{7}|\\d9\\d{2}))|3(?:1\\d{4}(?:\\d{3})?|[3-6]\\d{7})",,,,"211234567"],[,,"7(?:[0-8]\\d{2}|99\\d)\\d{5}",,,,"712345678",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"90[036]\\d{6}",,,,"900123456",,,[9]],[,,"801\\d{6}",,,,"801123456",,,[9]],[,,,
44015			,,,,,,[-1]],[,,,,,,,,,[-1]],"RO",40,"00","0"," int ",,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[23]1"],"0$1"],[,"(\\d{2})(\\d{4})","$1 $2",["[23]1"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[23][3-7]|[7-9]"],"0$1"],[,"(2\\d{2})(\\d{3})","$1 $2",["2[3-6]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"37\\d{7}",,,,"372123456",,,[9]],,,[,,,,,,,,,[-1]]],RS:[,[,,"[126-9]\\d{4,11}|3(?:[0-79]\\d{3,10}|8[2-9]\\d{2,9})",,,,,,,[6,7,8,9,10,11,12],[5]],[,,"(?:1(?:[02-9][2-9]|1[1-9])\\d|2(?:[0-24-7][2-9]\\d|[389](?:0[2-9]|[2-9]\\d))|3(?:[0-8][2-9]\\d|9(?:[2-9]\\d|0[2-9])))\\d{3,8}",
44016			,,,"10234567",,,[7,8,9,10,11,12],[5,6]],[,,"6(?:[0-689]|7\\d)\\d{6,7}",,,,"601234567",,,[8,9,10]],[,,"800\\d{3,9}",,,,"80012345"],[,,"(?:90[0169]|78\\d)\\d{3,7}",,,,"90012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"RS",381,"00","0",,,"0",,,,[[,"([23]\\d{2})(\\d{4,9})","$1 $2",["(?:2[389]|39)0"],"0$1"],[,"([1-3]\\d)(\\d{5,10})","$1 $2",["1|2(?:[0-24-7]|[389][1-9])|3(?:[0-8]|9[1-9])"],"0$1"],[,"(6\\d)(\\d{6,8})","$1 $2",["6"],"0$1"],[,"([89]\\d{2})(\\d{3,9})","$1 $2",["[89]"],"0$1"],[,"(7[26])(\\d{4,9})",
44017			"$1 $2",["7[26]"],"0$1"],[,"(7[08]\\d)(\\d{4,9})","$1 $2",["7[08]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"7[06]\\d{4,10}",,,,"700123456"],,,[,,,,,,,,,[-1]]],RU:[,[,,"[3489]\\d{9}",,,,,,,[10]],[,,"(?:3(?:0[12]|4[1-35-79]|5[1-3]|65|8[1-58]|9[0145])|4(?:01|1[1356]|2[13467]|7[1-5]|8[1-7]|9[1-689])|8(?:1[1-8]|2[01]|3[13-6]|4[0-8]|5[15]|6[1-35-79]|7[1-37-9]))\\d{7}",,,,"3011234567"],[,,"9\\d{9}",,,,"9123456789"],[,,"80[04]\\d{7}",,,,"8001234567"],[,,"80[39]\\d{7}",,,,"8091234567"],[,,,,,,,,,[-1]],
44018			[,,"808\\d{7}",,,,"8081234567"],[,,,,,,,,,[-1]],"RU",7,"810","8",,,"8",,"8~10",,[[,"(\\d{3})(\\d{2})(\\d{2})","$1-$2-$3",["[1-79]"],"$1",,1],[,"([3489]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4",["[34689]"],"8 ($1)",,1],[,"(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"8 ($1)",,1]],[[,"([3489]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4",["[34689]"],"8 ($1)",,1],[,"(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"8 ($1)",,1]],[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],RW:[,
44019			[,,"[027-9]\\d{7,8}",,,,,,,[8,9]],[,,"2[258]\\d{7}|06\\d{6}",,,,"250123456"],[,,"7[238]\\d{7}",,,,"720123456",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"900\\d{6}",,,,"900123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"RW",250,"00","0",,,"0",,,,[[,"(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["2"],"$1"],[,"([7-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[7-9]"],"0$1"],[,"(0\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,
44020				,[-1]]],SA:[,[,,"1\\d{7,8}|(?:[2-467]|92)\\d{7}|5\\d{8}|8\\d{9}",,,,,,,[8,9,10],[7]],[,,"11\\d{7}|1?(?:2[24-8]|3[35-8]|4[3-68]|6[2-5]|7[235-7])\\d{6}",,,,"112345678",,,[8,9],[7]],[,,"(?:5(?:[013-689]\\d|7[0-36-8])|811\\d)\\d{6}",,,,"512345678",,,[9,10]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,,,,,,,,[-1]],[,,"92[05]\\d{6}",,,,"920012345",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SA",966,"00","0",,,"0",,,,[[,"([1-467])(\\d{3})(\\d{4})","$1 $2 $3",["[1-467]"],"0$1"],[,"(1\\d)(\\d{3})(\\d{4})","$1 $2 $3",
44021			["1[1-467]"],"0$1"],[,"(5\\d)(\\d{3})(\\d{4})","$1 $2 $3",["5"],"0$1"],[,"(92\\d{2})(\\d{5})","$1 $2",["92"],"$1"],[,"(800)(\\d{3})(\\d{4})","$1 $2 $3",["80"],"$1"],[,"(811)(\\d{3})(\\d{3,4})","$1 $2 $3",["81"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SB:[,[,,"[1-9]\\d{4,6}",,,,,,,[5,7]],[,,"(?:1[4-79]|[23]\\d|4[0-2]|5[03]|6[0-37])\\d{3}",,,,"40123",,,[5]],[,,"48\\d{3}|7(?:30|[46-8]\\d|5[025-9]|9[0-5])\\d{4}|8[4-9]\\d{5}|9(?:1[2-9]|2[013-9]|3[0-2]|[46]\\d|5[0-46-9]|7[0-689]|8[0-79]|9[0-8])\\d{4}",
44022			,,,"7421234"],[,,"1[38]\\d{3}",,,,"18123",,,[5]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5[12]\\d{3}",,,,"51123",,,[5]],"SB",677,"0[01]",,,,,,,,[[,"(\\d{2})(\\d{5})","$1 $2",["[7-9]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SC:[,[,,"[24689]\\d{5,6}",,,,,,,[7]],[,,"4[2-46]\\d{5}",,,,"4217123"],[,,"2[5-8]\\d{5}",,,,"2510123"],[,,"8000\\d{3}",,,,"8000000"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:64\\d|971)\\d{4}",,,,"6412345"],"SC",248,"0(?:[02]|10?)",
44023			,,,,,"00",,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[246]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SD:[,[,,"[19]\\d{8}",,,,,,,[9]],[,,"1(?:[125]\\d|8[3567])\\d{6}",,,,"121231234"],[,,"9[0-3569]\\d{7}",,,,"911231234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SD",249,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SE:[,[,,"[1-35-9]\\d{5,11}|4\\d{6,8}",
44024			,,,,,,[6,7,8,9,10,12]],[,,"1(?:0[1-8]\\d{6}|[136]\\d{5,7}|(?:2[0-35]|4[0-4]|5[0-25-9]|7[13-6]|[89]\\d)\\d{5,6})|2(?:[136]\\d{5,7}|(?:2[0-7]|4[0136-8]|5[0138]|7[018]|8[01]|9[0-57])\\d{5,6})|3(?:[356]\\d{5,7}|(?:0[0-4]|1\\d|2[0-25]|4[056]|7[0-2]|8[0-3]|9[023])\\d{5,6})|4(?:[0246]\\d{5,7}|(?:1[013-8]|3[0135]|5[14-79]|7[0-246-9]|8[0156]|9[0-689])\\d{5,6})|5(?:0[0-6]|[15][0-5]|2[0-68]|3[0-4]|4\\d|6[03-5]|7[013]|8[0-79]|9[01])\\d{5,6}|6(?:[03]\\d{5,7}|(?:1[1-3]|2[0-4]|4[02-57]|5[0-37]|6[0-3]|7[0-2]|8[0247]|9[0-356])\\d{5,6})|8\\d{6,8}|9(?:0[1-9]\\d{4,6}|(?:1[0-68]|2\\d|3[02-5]|4[0-3]|5[0-4]|[68][01]|7[0135-8])\\d{5,6})",
44025			,,,"8123456",,,[7,8,9]],[,,"7[02369]\\d{7}",,,,"701234567",,,[9]],[,,"20\\d{4,7}",,,,"20123456",,,[6,7,8,9]],[,,"649\\d{6}|9(?:00|39|44)[1-8]\\d{3,6}",,,,"9001234567",,,[7,8,9,10]],[,,"77(?:0\\d{3}(?:\\d{3})?|[1-7]\\d{6})",,,,"771234567",,,[6,9]],[,,"75[1-8]\\d{6}",,,,"751234567",,,[9]],[,,,,,,,,,[-1]],"SE",46,"00","0",,,"0",,,,[[,"(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1-$2 $3 $4",["8"],"0$1"],[,"([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1-$2 $3 $4",["1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|90"],"0$1"],
44026			[,"([1-469]\\d)(\\d{3})(\\d{2})","$1-$2 $3",["1[136]|2[136]|3[356]|4[0246]|6[03]|90"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1-$2 $3 $4",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"],"0$1"],[,"(\\d{3})(\\d{2,3})(\\d{2})","$1-$2 $3",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"],"0$1"],[,"(7\\d)(\\d{3})(\\d{2})(\\d{2})","$1-$2 $3 $4",["7"],"0$1"],[,"(77)(\\d{2})(\\d{2})",
44027				"$1-$2$3",["7"],"0$1"],[,"(20)(\\d{2,3})(\\d{2})","$1-$2 $3",["20"],"0$1"],[,"(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})","$1-$2 $3 $4",["9[034]"],"0$1"],[,"(9[034]\\d)(\\d{4})","$1-$2",["9[034]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1-$2 $3 $4 $5",["25[245]|67[3-6]"],"0$1"]],[[,"(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1 $2 $3 $4",["8"]],[,"([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|90"]],[,"([1-469]\\d)(\\d{3})(\\d{2})","$1 $2 $3",["1[136]|2[136]|3[356]|4[0246]|6[03]|90"]],
44028			[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"]],[,"(\\d{3})(\\d{2,3})(\\d{2})","$1 $2 $3",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"]],[,"(7\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["7"]],[,"(77)(\\d{2})(\\d{2})","$1 $2 $3",["7"]],[,"(20)(\\d{2,3})(\\d{2})","$1 $2 $3",["20"]],[,"(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})",
44029				"$1 $2 $3 $4",["9[034]"]],[,"(9[034]\\d)(\\d{4})","$1 $2",["9[034]"]],[,"(\\d{3})(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["25[245]|67[3-6]"]]],[,,"74[02-9]\\d{6}",,,,"740123456",,,[9]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,"(?:25[245]|67[3-6])\\d{9}
44029",,,,"254123456789",,,[12]]],SG:[,[,,"[36]\\d{7}|[17-9]\\d{7,10}",,,,,,,[8,10,11]],[,,"6[1-9]\\d{6}",,,,"61234567",,,[8]],[,,"(?:8[1-8]|9[0-8])\\d{6}",,,,"81234567",,,[8]],[,,"1?800\\d{7}",,,,"18001234567",,,[10,11]],[,,"1900\\d{7}",,,,"19001234567",
44030			,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3[12]\\d{6}",,,,"31234567",,,[8]],"SG",65,"0[0-3]\\d",,,,,,,,[[,"([3689]\\d{3})(\\d{4})","$1 $2",["[369]|8[1-9]"]],[,"(1[89]00)(\\d{3})(\\d{4})","$1 $2 $3",["1[89]"]],[,"(7000)(\\d{4})(\\d{3})","$1 $2 $3",["70"]],[,"(800)(\\d{3})(\\d{4})","$1 $2 $3",["80"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"7000\\d{7}",,,,"70001234567",,,[11]],,,[,,,,,,,,,[-1]]],SH:[,[,,"[256]\\d{4}",,,,,,,[4,5]],[,,"2(?:[0-57-9]\\d|6[4-9])\\d{2}",,,,"22158"],[,,"[56]\\d{4}",,,,"51234",
44031			,,[5]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"262\\d{2}",,,,"26212",,,[5]],"SH",290,"00",,,,,,,,,,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SI:[,[,,"[1-7]\\d{6,7}|[89]\\d{4,7}",,,,,,,[5,6,7,8]],[,,"(?:1\\d|[25][2-8]|3[24-8]|4[24-8]|7[3-8])\\d{6}",,,,"11234567",,,[8],[7]],[,,"(?:[37][01]\\d|4[0139]\\d|51\\d|6(?:[48]\\d|9[69]))\\d{5}",,,,"31234567",,,[8]],[,,"80\\d{4,6}",,,,"80123456",,,[6,7,8]],[,,"90\\d{4,6}|89[1-3]\\d{2,5}",,,,"90123456"],
44032			[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:59|8[1-3])\\d{6}",,,,"59012345",,,[8]],"SI",386,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[12]|3[24-8]|4[24-8]|5[2-8]|7[3-8]"],"(0$1)"],[,"([3-7]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[37][01]|4[0139]|51|6"],"0$1"],[,"([89][09])(\\d{3,6})","$1 $2",["[89][09]"],"0$1"],[,"([58]\\d{2})(\\d{5})","$1 $2",["59|8[1-3]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SJ:[,[,,"0\\d{4}|[45789]\\d{7}",,,,,,,[5,8]],[,
44033			,"79\\d{6}",,,,"79123456",,,[8]],[,,"(?:4[015-8]|5[89]|9\\d)\\d{6}",,,,"41234567",,,[8]],[,,"80[01]\\d{5}",,,,"80012345",,,[8]],[,,"82[09]\\d{5}",,,,"82012345",,,[8]],[,,"810(?:0[0-6]|[2-8]\\d)\\d{3}",,,,"81021234",,,[8]],[,,"880\\d{5}",,,,"88012345",,,[8]],[,,"85[0-5]\\d{5}",,,,"85012345",,,[8]],"SJ",47,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"0\\d{4}|81(?:0(?:0[7-9]|1\\d)|5\\d{2})\\d{3}",,,,"01234"],,,[,,"81[23]\\d{5}",,,,"81212345",,,[8]]],SK:[,[,,"(?:[2-68]\\d{5,8}|9\\d{6,8})",,,,,
44034			,,[6,7,9]],[,,"2(?:1(?:6\\d{3,4}|7\\d{3})|[2-9]\\d{7})|[3-5][1-8](?:1(?:6\\d{2,3}|7\\d{3})|\\d{7})",,,,"221234567"],[,,"9(?:0(?:[1-8]\\d|9[1-9])|(?:1[0-24-9]|[45]\\d)\\d)\\d{5}",,,,"912123456",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"9(?:[78]\\d{7}|00\\d{6})",,,,"900123456",,,[9]],[,,"8[5-9]\\d{7}",,,,"850123456",,,[9]],[,,,,,,,,,[-1]],[,,"6(?:02|5[0-4]|9[0-6])\\d{6}",,,,"690123456",,,[9]],"SK",421,"00","0",,,"0",,,,[[,"(2)(1[67])(\\d{3,4})","$1 $2 $3",["21[67]"],"0$1"],[,"([3-5]\\d)(1[67])(\\d{2,3})",
44035			"$1 $2 $3",["[3-5]"],"0$1"],[,"(2)(\\d{3})(\\d{3})(\\d{2})","$1/$2 $3 $4",["2"],"0$1"],[,"([3-5]\\d)(\\d{3})(\\d{2})(\\d{2})","$1/$2 $3 $4",["[3-5]"],"0$1"],[,"([689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[689]"],"0$1"],[,"(9090)(\\d{3})","$1 $2",["9090"],"0$1"]],,[,,"9090\\d{3}",,,,"9090123",,,[7]],,,[,,"(?:602|8(?:00|[5-9]\\d)|9(?:00|[78]\\d))\\d{6}|9090\\d{3}",,,,"800123456",,,[7,9]],[,,"96\\d{7}",,,,"961234567",,,[9]],,,[,,,,,,,,,[-1]]],SL:[,[,,"[2-9]\\d{7}",,,,,,,[8],[6]],[,,"[235]2[2-4][2-9]\\d{4}",
44036			,,,"22221234",,,,[6]],[,,"(?:2[15]|3[03-5]|4[04]|5[05]|66|7[6-9]|8[08]|99)\\d{6}",,,,"25123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SL",232,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",,"(0$1)"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SM:[,[,,"[05-7]\\d{7,9}",,,,,,,[8,10],[6]],[,,"0549(?:8[0157-9]|9\\d)\\d{4}",,,,"0549886377",,,[10],[6]],[,,"6[16]\\d{6}",,,,"66661212",,,[8]],[,,,,,,,,,[-1]],[,,"7[178]\\d{6}",,,,"71123456",
44037			,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5[158]\\d{6}",,,,"58001110",,,[8]],"SM",378,"00",,,,"(?:0549)?([89]\\d{5})","0549$1",,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[5-7]"]],[,"(0549)(\\d{6})","$1 $2",["0"]],[,"(\\d{6})","0549 $1",["[89]"]]],[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[5-7]"]],[,"(0549)(\\d{6})","($1) $2",["0"]],[,"(\\d{6})","(0549) $1",["[89]"]]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SN:[,[,,"[3789]\\d{8}",,,,,,,[9]],[,
44038			,"3(?:0(?:1[0-2]|80)|282|3(?:8[1-9]|9[3-9])|611)\\d{5}
44038",,,,"301012345"],[,,"7(?:[06-8]\\d|21|90)\\d{6}",,,,"701234567"],[,,"800\\d{6}",,,,"800123456"],[,,"88[4689]\\d{6}",,,,"884123456"],[,,"81[02468]\\d{6}",,,,"810123456"],[,,,,,,,,,[-1]],[,,"39[01]\\d{6}|3392\\d{5}|93330\\d{4}",,,,"933301234"],"SN",221,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[379]"]],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,
44039			,,[-1]]],SO:[,[,,"[1-9]\\d{5,8}",,,,,,,[6,7,8,9]],[,,"(?:1\\d{1,2}|2[0-79]\\d|3[0-46-8]?\\d|4[0-7]?\\d|59\\d|8[125])\\d{4}",,,,"4012345",,,[6,7]],[,,"(?:15\\d|2(?:4\\d|8)|3[59]\\d{2}|4[89]\\d{2}|6[1-9]?\\d{2}|7(?:[1-8]\\d|9\\d{1,2})|8[08]\\d{2}|9(?:0[67]|[2-9])\\d)\\d{5}",,,,"71123456",,,[7,8,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SO",252,"00","0",,,"0",,,,[[,"(\\d{6})","$1",["[134]"]],[,"(\\d)(\\d{6})","$1 $2",["2[0-79]|[13-5]"]],[,"(\\d)(\\d{7})","$1 $2",
44040			["24|[67]"]],[,"(\\d{2})(\\d{4})","$1 $2",["8[125]"]],[,"(\\d{2})(\\d{5,7})","$1 $2",["15|28|6[1-35-9]|799|9[2-9]"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["3[59]|4[89]|6[24-6]|79|8[08]|90"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SR:[,[,,"[2-8]\\d{5,6}",,,,,,,[6,7]],[,,"(?:2[1-3]|3[0-7]|4\\d|5[2-58]|68\\d)\\d{4}",,,,"211234"],[,,"(?:7[124-7]|8[1-9])\\d{5}",,,,"7412345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"56\\d{4}",,,,"561234",
44041			,,[6]],"SR",597,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1-$2",["[2-4]|5[2-58]"]],[,"(\\d{2})(\\d{2})(\\d{2})","$1-$2-$3",["56"]],[,"(\\d{3})(\\d{4})","$1-$2",["[6-8]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SS:[,[,,"[19]\\d{8}",,,,,,,[9]],[,,"18\\d{7}",,,,"181234567"],[,,"(?:12|9[1257])\\d{7}",,,,"977123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SS",211,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",,"0$1"]],,[,,
44042			,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ST:[,[,,"[29]\\d{6}",,,,,,,[7]],[,,"22\\d{5}",,,,"2221234"],[,,"9(?:0(?:0[5-9]|[1-9]\\d)|[89]\\d{2})\\d{3}",,,,"9812345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ST",239,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SV:[,[,,"[267]\\d{7}|[89]\\d{6}(?:\\d{4})?",,,,,,,[7,8,11]],[,,"2[1-6]\\d{6}",,,,"21234567",,,[8]],[,,"[67]\\d{7}",
44043			,,,"70123456",,,[8]],[,,"800\\d{4}(?:\\d{4})?",,,,"8001234",,,[7,11]],[,,"900\\d{4}(?:\\d{4})?",,,,"9001234",,,[7,11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SV",503,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[267]"]],[,"(\\d{3})(\\d{4})","$1 $2",["[89]"]],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["[89]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SX:[,[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"7215(?:4[2-8]|8[239]|9[056])\\d{4}",,,,"7215425678",,,,[7]],[,,"7215(?:1[02]|2\\d|5[034679]|8[014-8])\\d{4}",
44044			,,,"7215205678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"SX",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"721",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SY:[,[,,"[1-59]\\d{7,8}",,,,,,,[8,9],[6,7]],[,,"(?:1(?:1\\d?|4\\d|[2356])|2(?:1\\d?|[235])|3(?:[13]\\d|4)|4[13]|5[1-3])\\d{6}",,,,"112345678",,,,[6,7]],[,,"9(?:22|[3-589]\\d|6[024-9])\\d{6}",
44045			,,,"944567890",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SY",963,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["[1-5]"],"0$1",,1],[,"(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["9"],"0$1",,1]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SZ:[,[,,"[027]\\d{7}",,,,,,,[8]],[,,"2[2-9]\\d{6}",,,,"22171234"],[,,"7[6-9]\\d{6}",,,,"76123456"],[,,"0800\\d{4}",,,,"08001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,
44046			,,,,,,,[-1]],"SZ",268,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[027]"]]],,[,,,,,,,,,[-1]],,,[,,"0800\\d{4}",,,,"08001234"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TA:[,[,,"8\\d{3}",,,,,,,[4]],[,,"8\\d{3}",,,,"8999"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TA",290,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TC:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"649(?:712|9(?:4\\d|50))\\d{4}",,,,"6497121234",,,,[7]],[,
44047			,"649(?:2(?:3[129]|4[1-7])|3(?:3[1-389]|4[1-8])|4[34][1-3])\\d{4}",,,,"6492311234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,"64971[01]\\d{4}",,,,"6497101234",,,,[7]],"TC",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"649",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TD:[,[,,"[2679]\\d{7}",,,,,,,[8]],[,,"22(?:[3789]0|5[0-5]|6[89])\\d{4}",,,,"22501234"],[,,"(?:6[023568]\\d|77\\d|9\\d{2})\\d{5}",
44048			,,,"63012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TD",235,"00|16",,,,,,"00",,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TG:[,[,,"[29]\\d{7}",,,,,,,[8]],[,,"2(?:2[2-7]|3[23]|44|55|66|77)\\d{5}",,,,"22212345"],[,,"9[0-36-9]\\d{6}",,,,"90112345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TG",228,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
44049			"$1 $2 $3 $4",["[29]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TH:[,[,,"1\\d{8,9}|[2-9]\\d{7,8}",,,,,,,[8,9,10]],[,,"(?:2\\d|3[2-9]|4[2-5]|5[2-6]|7[3-7])\\d{6}",,,,"21234567",,,[8]],[,,"(?:14|6[1-6]|[89]\\d)\\d{7}",,,,"812345678",,,[9]],[,,"1800\\d{6}",,,,"1800123456",,,[10]],[,,"1900\\d{6}",,,,"1900123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"6[08]\\d{7}",,,,"601234567",,,[9]],"TH",66,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3",["2"],"0$1"],[,"([13-9]\\d)(\\d{3})(\\d{3,4})",
44050			"$1 $2 $3",["14|[3-9]"],"0$1"],[,"(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3",["1"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TJ:[,[,,"[3-57-9]\\d{8}",,,,,,,[9],[3,5,7]],[,,"(?:3(?:1[3-5]|2[245]|3[12]|4[24-7]|5[25]|72)|4(?:46|74|87))\\d{6}",,,,"372123456",,,,[3,5,7]],[,,"(?:41[18]|(?:5[05]|77|88|9[0-35-9])\\d)\\d{6}",,,,"917123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TJ",992,"810","8",,,"8",,"8~10",,[[,"([349]\\d{2})(\\d{2})(\\d{4})",
44051			"$1 $2 $3",["[34]7|91[78]"],"$1",,1],[,"([457-9]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["4[148]|[578]|9(?:1[59]|[0235-9])"],"$1",,1],[,"(331700)(\\d)(\\d{2})","$1 $2 $3",["331","3317","33170","331700"],"$1",,1],[,"(\\d{4})(\\d)(\\d{4})","$1 $2 $3",["3[1-5]","3(?:[1245]|3(?:[02-9]|1[0-589]))"],"$1",,1]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TK:[,[,,"[2-47]\\d{3,6}",,,,,,,[4,5,6,7]],[,,"(?:2[2-4]|[34]\\d)\\d{2,5}",,,,"3101"],[,,"7[2-4]\\d{2,5}",,,,"7290"],[,,,,,,,,,[-1]],[,
44052			,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TK",690,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TL:[,[,,"[2-489]\\d{6}|7\\d{6,7}",,,,,,,[7,8]],[,,"(?:2[1-5]|3[1-9]|4[1-4])\\d{5}",,,,"2112345",,,[7]],[,,"7[3-8]\\d{6}",,,,"77212345",,,[8]],[,,"80\\d{5}",,,,"8012345",,,[7]],[,,"90\\d{5}",,,,"9012345",,,[7]],[,,,,,,,,,[-1]],[,,"70\\d{5}",,,,"7012345",,,[7]],[,,,,,,,,,[-1]],"TL",670,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[2-489]|70"]],[,"(\\d{4})(\\d{4})",
44053			"$1 $2",["7[3-8]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TM:[,[,,"[1-6]\\d{7}",,,,,,,[8]],[,,"(?:1(?:2\\d|3[1-9])|2(?:22|4[0-35-8])|3(?:22|4[03-9])|4(?:22|3[128]|4\\d|6[15])|5(?:22|5[7-9]|6[014-689]))\\d{5}",,,,"12345678"],[,,"6[1-9]\\d{6}",,,,"66123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TM",993,"810","8",,,"8",,"8~10",,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2-$3-$4",["12"],"(8 $1)"],[,"(\\d{2})(\\d{6})","$1 $2",
44054			["6"],"8 $1"],[,"(\\d{3})(\\d)(\\d{2})(\\d{2})","$1 $2-$3-$4",["13|[2-5]"],"(8 $1)"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TN:[,[,,"[2-57-9]\\d{7}",,,,,,,[8]],[,,"3(?:[012]\\d|6[0-4]|91)\\d{5}|7\\d{7}|81200\\d{3}",,,,"71234567"],[,,"(?:[259]\\d|4[0-6])\\d{6}",,,,"20123456"],[,,"8010\\d{4}",,,,"80101234"],[,,"88\\d{6}",,,,"88123456"],[,,"8[12]10\\d{4}",,,,"81101234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TN",216,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3"]],,[,
44055			,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TO:[,[,,"[02-8]\\d{4,6}",,,,,,,[5,7]],[,,"(?:2\\d|3[1-8]|4[1-4]|[56]0|7[0149]|8[05])\\d{3}",,,,"20123",,,[5]],[,,"(?:7[578]|8[47-9])\\d{5}",,,,"7715123",,,[7]],[,,"0800\\d{3}",,,,"0800222",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TO",676,"00",,,,,,,,[[,"(\\d{2})(\\d{3})","$1-$2",["[1-6]|7[0-4]|8[05]"]],[,"(\\d{3})(\\d{4})","$1 $2",["7[5-9]|8[47-9]"]],[,"(\\d{4})(\\d{3})","$1 $2",["0"]]],,[,,,,,,,,,[-1]],
44056			,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TR:[,[,,"[2-589]\\d{9}|444\\d{4}",,,,,,,[7,10]],[,,"(?:2(?:[13][26]|[28][2468]|[45][268]|[67][246])|3(?:[13][28]|[24-6][2468]|[78][02468]|92)|4(?:[16][246]|[23578][2468]|4[26]))\\d{7}",,,,"2123456789",,,[10]],[,,"5(?:(?:0[1-7]|22|[34]\\d|5[1-59]|9[246])\\d{2}|6161)\\d{5}",,,,"5012345678",,,[10]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TR",90,"00","0",,,"0",,,
44057			,[[,"(\\d{3})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[23]|4(?:[0-35-9]|4[0-35-9])"],"(0$1)",,1],[,"(\\d{3})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["5[02-69]"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["51|[89]"],"0$1",,1],[,"(444)(\\d{1})(\\d{3})","$1 $2 $3",["444"]]],,[,,"512\\d{7}",,,,"5123456789",,,[10]],,,[,,"444\\d{4}",,,,"4441444",,,[7]],[,,"444\\d{4}|850\\d{7}",,,,"4441444"],,,[,,,,,,,,,[-1]]],TT:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"868(?:2(?:01|[23]\\d)|6(?:0[79]|1[02-8]|2[1-9]|[3-69]\\d|7[0-79])|82[124])\\d{4}",
44058			,,,"8682211234",,,,[7]],[,,"868(?:2(?:6[6-9]|[789]\\d)|3(?:0[1-9]|1[02-9]|[2-9]\\d)|4[6-9]\\d|6(?:20|78|8\\d)|7(?:0[1-9]|1[02-9]|[2-9]\\d))\\d{4}",,,,"8682911234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"TT",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"868",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,"868619\\d{4}",,,,"8686191234",,,,[7]]],TV:[,[,,"[279]\\d{4,6}",
44059			,,,,,,[5,6,7]],[,,"2[02-9]\\d{3}",,,,"20123",,,[5]],[,,"(?:70\\d|90)\\d{4}",,,,"901234",,,[6,7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TV",688,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TW:[,[,,"2\\d{6,8}|[3-689]\\d{7,8}|7\\d{7,9}",,,,,,,[7,8,9,10]],[,,"2(?:[235-8]\\d{7}|4\\d{6,7})|[3-8]\\d{7,8}",,,,"221234567",,,[8,9]],[,,"9\\d{8}",,,,"912345678",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"20(?:2|[013-9]\\d{2})\\d{4}",
44060			,,,"203123456",,,[7,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"70\\d{8}",,,,"7012345678",,,[10]],"TW",886,"0(?:0[25679]|19)","0","#",,"0",,,,[[,"(20)(\\d)(\\d{4})","$1 $2 $3",["202"],"0$1"],[,"(20)(\\d{3})(\\d{4})","$1 $2 $3",["20[013-9]"],"0$1"],[,"([2-8])(\\d{3,4})(\\d{4})","$1 $2 $3",["2[23-8]|[3-6]|[78][1-9]"],"0$1"],[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["80|9"],"0$1"],[,"(70)(\\d{4})(\\d{4})","$1 $2 $3",["70"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
44061		TZ:[,[,,"\\d{9}",,,,,,,[7,9]],[,,"2[2-8]\\d{7}",,,,"222345678"],[,,"(?:6[2-9]|7[13-9])\\d{7}",,,,"621234567",,,[9]],[,,"80[08]\\d{6}",,,,"800123456",,,[9]],[,,"90\\d{7}",,,,"900123456",,,[9]],[,,"8(?:40|6[01])\\d{6}",,,,"840123456",,,[9]],[,,,,,,,,,[-1]],[,,"41\\d{7}
44061",,,,"412345678",,,[9]],"TZ",255,"00[056]","0",,,"0",,,,[[,"([24]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[24]"],"0$1"],[,"([67]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[67]"],"0$1"],[,"([89]\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",["[89]"],"0$1"]],
44062			,[,,,,,,,,,[-1]],,,[,,"(?:8(?:[04]0|6[01])|90\\d)\\d{6}",,,,"800123456",,,[9]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UA:[,[,,"[3-9]\\d{8}",,,,,,,[9],[5,6,7]],[,,"(?:3[1-8]|4[13-8]|5[1-7]|6[12459])\\d{7}",,,,"311234567",,,,[5,6,7]],[,,"(?:39|50|6[36-8]|7[1-3]|9[1-9])\\d{7}",,,,"391234567"],[,,"800\\d{6}",,,,"800123456"],[,,"900[2-49]\\d{5}",,,,"900212345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"89\\d{7}",,,,"891234567"],"UA",380,"00","0",,,"0",,"0~0",,[[,"([3-9]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[38]9|4(?:[45][0-5]|87)|5(?:0|6[37]|7[37])|6[36-8]|7|9[1-9]",
44063			"[38]9|4(?:[45][0-5]|87)|5(?:0|6(?:3[14-7]|7)|7[37])|6[36-8]|7|9[1-9]"],"0$1"],[,"([3-689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["3[1-8]2|4[13678]2|5(?:[12457]2|6[24])|6(?:[49]2|[12][29]|5[24])|8[0-8]|90","3(?:[1-46-8]2[013-9]|52)|4(?:[1378]2|62[013-9])|5(?:[12457]2|6[24])|6(?:[49]2|[12][29]|5[24])|8[0-8]|90"],"0$1"],[,"([3-6]\\d{3})(\\d{5})","$1 $2",["3(?:5[013-9]|[1-46-8])|4(?:[137][013-9]|6|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6[0135-9]|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])","3(?:5[013-9]|[1-46-8](?:22|[013-9]))|4(?:[137][013-9]|6(?:[013-9]|22)|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6(?:3[02389]|[015689])|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])"],
44064			"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UG:[,[,,"\\d{9}",,,,,,,[9],[5,6,7]],[,,"20(?:[0147]\\d{2}|2(?:40|[5-9]\\d)|3(?:0[0-4]|[23]\\d)|5[0-4]\\d|6[035-9]\\d|8[0-2]\\d)\\d{4}|[34]\\d{8}",,,,"312345678",,,,[5,6,7]],[,,"7(?:(?:0[0-7]|[15789]\\d|30|4[0-4])\\d|2(?:[03]\\d|60))\\d{5}",,,,"712345678"],[,,"800[123]\\d{5}",,,,"800123456"],[,,"90[123]\\d{6}",,,,"901123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"UG",256,"00[057]","0",,,"0",,,,[[,"(\\d{3})(\\d{6})",
44065			"$1 $2",["[7-9]|20(?:[013-8]|2[5-9])|4(?:6[45]|[7-9])"],"0$1"],[,"(\\d{2})(\\d{7})","$1 $2",["3|4(?:[1-5]|6[0-36-9])"],"0$1"],[,"(2024)(\\d{5})","$1 $2",["2024"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],US:[,[,,"[2-9]\\d{9}",,,,,,,[10],[7]],[,,"(?:2(?:0[1-35-9]|1[02-9]|2[04589]|3[149]|4[08]|5[1-46]|6[0279]|7[026]|8[13])|3(?:0[1-57-9]|1[02-9]|2[0135]|3[0-24679]|4[67]|5[12]|6[014]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[0235]|58|6[39]|7[0589]|8[04])|5(?:0[1-57-9]|1[0235-8]|20|3[0149]|4[01]|5[19]|6[1-47]|7[013-5]|8[056])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[16]|5[017]|6[0-279]|78|8[012])|7(?:0[1-46-8]|1[02-9]|2[0457]|3[1247]|4[037]|5[47]|6[02359]|7[02-59]|8[156])|8(?:0[1-68]|1[02-8]|28|3[0-25]|4[3578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[014678]|4[0179]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
44066			,,,"2015550123",,,,[7]],[,,"(?:2(?:0[1-35-9]|1[02-9]|2[04589]|3[149]|4[08]|5[1-46]|6[0279]|7[026]|8[13])|3(?:0[1-57-9]|1[02-9]|2[0135]|3[0-24679]|4[67]|5[12]|6[014]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[0235]|58|6[39]|7[0589]|8[04])|5(?:0[1-57-9]|1[0235-8]|20|3[0149]|4[01]|5[19]|6[1-47]|7[013-5]|8[056])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[16]|5[017]|6[0-279]|78|8[012])|7(?:0[1-46-8]|1[02-9]|2[0457]|3[1247]|4[037]|5[47]|6[02359]|7[02-59]|8[156])|8(?:0[1-68]|1[02-8]|28|3[0-25]|4[3578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[014678]|4[0179]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
44067			,,,"2015550123",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"US",1,"011","1",,,"1",,,1,[[,"(\\d{3})(\\d{4})","$1-$2",,,,1],[,"(\\d{3})(\\d{3})(\\d{4})","($1) $2-$3",,,,1]],[[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3"]],[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UY:[,[,,"[2489]\\d{6,7}",,,,,,,[7,8]],[,,"2\\d{7}|4[2-7]\\d{6}",,
44068			,,"21231234",,,[8],[7]],[,,"9[1-9]\\d{6}",,,,"94231234",,,[8]],[,,"80[05]\\d{4}",,,,"8001234",,,[7]],[,,"90[0-8]\\d{4}",,,,"9001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"UY",598,"0(?:1[3-9]\\d|0)","0"," int. ",,"0",,"00",,[[,"(\\d{4})(\\d{4})","$1 $2",["[24]"]],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["9[1-9]"],"0$1"],[,"(\\d{3})(\\d{4})","$1 $2",["[89]0"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UZ:[,[,,"[679]\\d{8}",,,,,,,[9],[7]],[,,"(?:6(?:1(?:22|3[124]|4[1-4]|5[123578]|64)|2(?:22|3[0-57-9]|41)|5(?:22|3[3-7]|5[024-8])|6\\d{2}|7(?:[23]\\d|7[69])|9(?:22|4[1-8]|6[135]))|7(?:0(?:5[4-9]|6[0146]|7[12456]|9[135-8])|1[12]\\d|2(?:22|3[1345789]|4[123579]|5[14])|3(?:2\\d|3[1578]|4[1-35-7]|5[1-57]|61)|4(?:2\\d|3[1-579]|7[1-79])|5(?:22|5[1-9]|6[1457])|6(?:22|3[12457]|4[13-8])|9(?:22|5[1-9])))\\d{5}",
44069			,,,"662345678",,,,[7]],[,,"6(?:1(?:2(?:98|2[01])|35[0-4]|50\\d|61[23]|7(?:[
4406901][017]|4\\d|55|9[5-9]))|2(?:11\\d|2(?:[12]1|9[01379])|5(?:[126]\\d|3[0-4])|7\\d{2})|5(?:19[01]|2(?:27|9[26])|30\\d|59\\d|7\\d{2})|6(?:2(?:1[5-9]|2[0367]|38|41|52|60)|3[79]\\d|4(?:56|83)|7(?:[07]\\d|1[017]|3[07]|4[047]|5[057]|67|8[0178]|9[79])|9[0-3]\\d)|7(?:2(?:24|3[237]|4[5-9]|7[15-8])|5(?:7[12]|8[0589])|7(?:0\\d|[39][07])|9(?:0\\d|7[079]))|9(?:2(?:1[1267]|5\\d|3[01]|7[0-4])|5[67]\\d|6(?:2[0-26]|8\\d)|7\\d{2}))\\d{4}|7(?:0\\d{3}|1(?:13[01]|6(?:0[47]|1[67]|66)|71[3-69]|98\\d)|2(?:2(?:2[79]|95)|3(?:2[5-9]|6[0-6])|57\\d|7(?:0\\d|1[17]|2[27]|3[37]|44|5[057]|66|88))|3(?:2(?:1[0-6]|21|3[469]|7[159])|33\\d|5(?:0[0-4]|5[579]|9\\d)|7(?:[0-3579]\\d|4[0467]|6[67]|8[078])|9[4-6]\\d)|4(?:2(?:29|5[0257]|6[0-7]|7[1-57])|5(?:1[0-4]|8\\d|9[5-9])|7(?:0\\d|1[024589]|2[0127]|3[0137]|[46][07]|5[01]|7[5-9]|9[079])|9(?:7[015-9]|[89]\\d))|5(?:112|2(?:0\\d|2[29]|[49]4)|3[1568]\\d|52[6-9]|7(?:0[01578]|1[017]|[23]7|4[047]|[5-7]\\d|8[78]|9[079]))|6(?:2(?:2[1245]|4[2-4])|39\\d|41[179]|5(?:[349]\\d|5[0-2])|7(?:0[017]|[13]\\d|22|44|55|67|88))|9(?:22[128]|3(?:2[0-4]|7\\d)|57[05629]|7(?:2[05-9]|3[37]|4\\d|60|7[2579]|87|9[07])))\\d{4}|9[0-57-9]\\d{7}",
44070			,,,"912345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"UZ",998,"810","8",,,"8",,"8~10",,[[,"([679]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"8 $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VA:[,[,,"(?:0(?:878\\d{5}|6698\\d{5})|[1589]\\d{5,10}|3(?:[12457-9]\\d{8}|[36]\\d{7,9}))",,,,,,,[6,8,9,10,11]],[,,"06698\\d{5}",,,,"0669812345",,,[10]],[,,"3(?:[12457-9]\\d{8}|6\\d{7,8}|3\\d{7,9})",,,,"3123456789",,,[9,10,11]],[,,"80(?:0\\d{6}|3\\d{3})",
44071			,,,"800123456",,,[6,9]],[,,"0878\\d{5}|1(?:44|6[346])\\d{6}|89(?:2\\d{3}|4(?:[0-4]\\d{2}|[5-9]\\d{4})|5(?:[0-4]\\d{2}|[5-9]\\d{6})|9\\d{6})",,,,"899123456",,,[6,8,9,10]],[,,"84(?:[08]\\d{6}|[17]\\d{3})",,,,"848123456",,,[6,9]],[,,"1(?:78\\d|99)\\d{6}",,,,"1781234567",,,[9,10]],[,,"55\\d{8}",,,,"5512345678",,,[10]],"VA",39,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,"848\\d{6}",,,,"848123456",,,[9]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VC:[,[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"784(?:266|3(?:6[6-9]|7\\d|8[0-24-6])|4(?:38|5[0-36-8]|8[0-8])|5(?:55|7[0-2]|93)|638|784)\\d{4}",
44072			,,,"7842661234",,,,[7]],[,,"784(?:4(?:3[0-5]|5[45]|89|9[0-58])|5(?:2[6-9]|3[0-4]))\\d{4}",,,,"7844301234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"VC",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"784",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VE:[,[,,"[24589]\\d{9}",,,,,,,[10],[7]],[,,"(?:2(?:12|3[457-9]|[58][1-9]|[467]\\d|9[1-6])|50[01])\\d{7}",
44073			,,,"2121234567",,,,[7]],[,,"4(?:1[24-8]|2[46])\\d{7}",,,,"4121234567"],[,,"800\\d{7}",,,,"8001234567"],[,,"900\\d{7}",,,,"9001234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"VE",58,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{7})","$1-$2",,"0$1","$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VG:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"284(?:(?:229|4(?:22|9[45])|774|8(?:52|6[459]))\\d{4}|496[0-5]\\d{3})",,,,"2842291234",,,,[7]],[,,"284(?:(?:3(?:0[0-3]|4[0-7]|68|9[34])|4(?:4[0-6]|68|99)|54[0-57])\\d{4}|496[6-9]\\d{3})",
44074			,,,"2843001234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"VG",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"284",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VI:[,[,,"[3589]\\d{9}",,,,,,,[10],[7]],[,,"340(?:2(?:01|2[0678]|44|77)|3(?:32|44)|4(?:22|7[34])|5(?:1[34]|55)|6(?:26|4[23]|77|9[023])|7(?:1[2-589]|27|7\\d)|884|998)\\d{4}",,,,"3406421234",
44075			,,,[7]],[,,"340(?:2(?:01|2[0678]|44|77)|3(?:32|44)|4(?:22|7[34])|5(?:1[34]|55)|6(?:26|4[23]|77|9[023])|7(?:1[2-589]|27|7\\d)|884|998)\\d{4}",,,,"3406421234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"VI",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],,"340",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VN:[,[,,"[167]\\d{6,9}|[2-59]\\d{7,9}|8\\d{6,8}",
44076			,,,,,,[7,8,9,10]],[,,"(?:2(?:0[3-9]|1[0-689]|2[0-25-9]|3[2-9]|[48][2-7]|5[124-9]|6[0-39]|7[0-7]|9[0-4679])|4\\d|5(?:0[01]|[5-9])|6(?:[0-46-8]|5[01])|7[0235
44076])\\d{7}|8(?:[2-5]\\d|6[236]|7[13])\\d{6}",,,,"2101234567",,,[9,10]],[,,"(?:9\\d|1(?:2\\d|6[2-9]|8[68]|99))\\d{7}|8(?:6[89]|8\\d|9[89])\\d{6}",,,,"912345678",,,[9,10]],[,,"1800\\d{4,6}",,,,"1800123456",,,[8,9,10]],[,,"1900\\d{4,6}",,,,"1900123456",,,[8,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"VN",84,"00","0",,,"0",,,,[[,"([17]99)(\\d{4})",
44077			"$1 $2",["[17]99"],"0$1",,1],[,"([48])(\\d{4})(\\d{4})","$1 $2 $3",["4|8(?:[2-5]|6[236]|7[13])"],"0$1",,1],[,"(\\d{2})(\\d{4})(\\d{3,4})","$1 $2 $3",["2[48]|5[5-9]|6[0-46-8]|7[0235]"],"0$1",,1],[,"(80)(\\d{5})","$1 $2",["80"],"0$1",,1],[,"(69\\d)(\\d{4,5})","$1 $2",["69"],"0$1",,1],[,"(\\d{3})(\\d{4})(\\d{3})","$1 $2 $3",["2[0-35-79]|50|65"],"0$1",,1],[,"([89]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8(?:8|9[89])|9"],"0$1",,1],[,"(1[2689]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["1(?:[26]|8[68]|99)"],
44078			"0$1",,1],[,"(86[89])(\\d{3})(\\d{3})","$1 $2 $3",["86[89]"],"0$1",,1],[,"(1[89]00)(\\d{4,6})","$1 $2",["1[89]0"],"$1",,1]],,[,,,,,,,,,[-1]],,,[,,"[17]99\\d{4}|69\\d{5,6}",,,,"1992000",,,[7,8]],[,,"[17]99\\d{4}|69\\d{5,6}|80\\d{5}",,,,"1992000",,,[7,8]],,,[,,,,,,,,,[-1]]],VU:[,[,,"[2-57-9]\\d{4,6}",,,,,,,[5,7]],[,,"(?:2[02-9]\\d|3(?:[5-7]\\d|8[0-8])|48[4-9]|88\\d)\\d{2}",,,,"22123",,,[5]],[,,"(?:5(?:7[2-5]|[0-689]\\d)|7[013-7]\\d)\\d{4}",,,,"5912345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,
44079			,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"VU",678,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[579]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"3[03]\\d{3}|900\\d{4}",,,,"30123"],,,[,,,,,,,,,[-1]]],WF:[,[,,"[4-8]\\d{5}",,,,,,,[6]],[,,"(?:50|68|72)\\d{4}",,,,"501234"],[,,"(?:50|68|72|8[23])\\d{4}",,,,"501234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"WF",681,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
44080			,,[,,"[48]0\\d{4}",,,,"401234"]],WS:[,[,,"[2-8]\\d{4,6}",,,,,,,[5,6,7]],[,,"(?:[2-5]\\d|6[1-9]|84\\d{2})\\d{3}",,,,"22123",,,[5,7]],[,,"(?:60|7[25-7]\\d)\\d{4}",,,,"601234",,,[6,7]],[,,"800\\d{3}",,,,"800123",,,[6]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"WS",685,"0",,,,,,,,[[,"(8\\d{2})(\\d{3,4})","$1 $2",["8"]],[,"(7\\d)(\\d{5})","$1 $2",["7"]],[,"(\\d{5})","$1",["[2-6]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],YE:[,[,,"[1-7]\\d{6,8}",,,,
44081			,,,[7,8,9],[6]],[,,"(?:1(?:7\\d|[2-68])|2[2-68]|3[2358]|4[2-58]|5[2-6]|6[3-58]|7[24-68])\\d{5}",,,,"1234567",,,[7,8],[6]],[,,"7[0137]\\d{7}",,,,"712345678",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"YE",967,"00","0",,,"0",,,,[[,"([1-7])(\\d{3})(\\d{3,4})","$1 $2 $3",["[1-6]|7[24-68]"],"0$1"],[,"(7\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["7[0137]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],YT:[,[,,"[268]\\d{8}",,,,,,,[9]],
44082			[,,"269(?:6[0-4]|50)\\d{4}",,,,"269601234"],[,,"639(?:0[0-79]|1[019]|[26]\\d|3[09]|[45]0|7[06]|9[04-79])\\d{4}",,,,"639012345"],[,,"80\\d{7}",,,,"801234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"YT",262,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,"269|63",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ZA:[,[,,"[1-79]\\d{8}|8\\d{4,8}",,,,,,,[5,6,7,8,9]],[,,"(?:1[0-8]|2[1-378]|3[1-69]|4\\d|5[1346-8])\\d{7}",,,,"101234567",,,[9]],[,,"(?:6\\d|7[0-46-9])\\d{7}|8(?:[1-4]\\d{1,5}|5\\d{5})\\d{2}",
44083			,,,"711234567"],[,,"80\\d{7}",,,,"801234567",,,[9]],[,,"86[2-9]\\d{6}|9[0-2]\\d{7}",,,,"862345678",,,[9]],[,,"860\\d{6}",,,,"860123456",,,[9]],[,,,,,,,,,[-1]],[,,"87\\d{7}",,,,"871234567",,,[9]],"ZA",27,"00","0",,,"0",,,,[[,"(860)(\\d{3})(\\d{3})","$1 $2 $3",["860"],"0$1"],[,"(\\d{2})(\\d{3,4})","$1 $2",["8[1-4]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3",["8[1-4]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[1-79]|8(?:[0-57]|6[1-9])"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"861\\d{6}",
44084			,,,"861123456",,,[9]],,,[,,,,,,,,,[-1]]],ZM:[,[,,"[289]\\d{8}",,,,,,,[9]],[,,"21[1-8]\\d{6}",,,,"211234567"],[,,"9(?:5[034589]|[67]\\d)\\d{6}",,,,"955123456"],[,,"800\\d{6}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ZM",260,"00","0",,,"0",,,,[[,"([29]\\d)(\\d{7})","$1 $2",["[29]"],"0$1"],[,"(800)(\\d{3})(\\d{3})","$1 $2 $3",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ZW:[,[,,"2(?:[0-2457-9]\\d{3,8}|6(?:[14]\\d{7}|\\d{4}))|[13-79]\\d{4,9}|8[06]\\d{5,8}",
44085			,,,,,,[5,6,7,8,9,10],[3,4]],[,,"(?:2(?:0(?:4\\d|5\\d{2})|2[278]\\d|48\\d|7(?:[1-7]\\d|[089]\\d{2})|8(?:[2-57-9]|[146]\\d{2})|98)|3(?:08|17|3[78]|7(?:[19]|[56]\\d)|8[37]|98)|5[15][78]|6(?:28\\d{2}|37|6[78]|75\\d|98|8(?:7\\d|8)))\\d{3}|(?:2(?:1[39]|2[0157]|31|[56][14]|7[35]|84)|329)\\d{7}|(?:1(?:3\\d{2}|[4-8]|9\\d)|2(?:0\\d{2}|12|292|[569]\\d)|3(?:[26]|[013459]\\d)|5(?:0|1[2-4]|26|[37]2|5\\d{2}|[689]\\d)|6(?:[39]|[01246]\\d|[78]\\d{2}))\\d{3}|(?:29\\d|39|54)\\d{6}|(?:(?:25|54)83\\d|2582\\d{2}|65[2-8])\\d{2}|(?:4\\d{6,7}|9[2-9]\\d{4,5})",
44086			,,,"1312345",,,,[3,4]],[,,"(?:7(?:1[2-8]|3[2-9]|7[1-9]|8[2-5])|8644)\\d{6}",,,,"712345678",,,[9,10]],[,,"80(?:[01]\\d|20|8[0-8])\\d{3}",,,,"8001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"86(?:1[12]|30|55|77|8[368])\\d{6}",,,,"8686123456",,,[10]],"ZW",263,"00","0",,,"0",,,,[[,"([49])(\\d{3})(\\d{2,4})","$1 $2 $3",["4|9[2-9]"],"0$1"],[,"(7\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["7"],"0$1"],[,"(86\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["86[24]"],"0$1"],[,"([2356]\\d{2})(\\d{3,5})","$1 $2",
44087			["2(?:0[45]|2[278]|[49]8|[78])|3(?:08|17|3[78]|7[1569]|8[37]|98)|5[15][78]|6(?:[29]8|[38]7|6[78]|75|[89]8)"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["2(?:1[39]|2[0157]|31|[56][14]|7[35]|84)|329"],"0$1"],[,"([1-356]\\d)(\\d{3,5})","$1 $2",["1[3-9]|2[02569]|3[0-69]|5[05689]|6\\d"],"0$1"],[,"([235]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[23]9|54"],"0$1"],[,"([25]\\d{3})(\\d{3,5})","$1 $2",["(?:25|54)8","258[23]|5483"],"0$1"],[,"(8\\d{3})(\\d{6})","$1 $2",["86"],"0$1"],[,"(80\\d)(\\d{4})","$1 $2",
44088			["80"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],800:[,[,,"\\d{8}",,,,,,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"\\d{8}",,,,"12345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",800,,,,,,,,1,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],808:[,[,,"\\d{8}",,,,,,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"\\d{8}",,,,"12345678"],[,,,,,,,,,[-1]],[,,,,,,
44089			,,,[-1]],"001",808,,,,,,,,1,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],870:[,[,,"[35-7]\\d{8}",,,,,,,[9]],[,,,,,,,,,[-1]],[,,"(?:[356]\\d|7[6-8])\\d{7}",,,,"301234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",870,,,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],878:[,[,,"1\\d{11}",,,,,,,[12]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
44090			[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"10\\d{10}",,,,"101234567890"],"001",878,,,,,,,,1,[[,"(\\d{2})(\\d{5})(\\d{5})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],881:[,[,,"[67]\\d{8}",,,,,,,[9]],[,,,,,,,,,[-1]],[,,"[67]\\d{8}",,,,"612345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",881,,,,,,,,,[[,"(\\d)(\\d{3})(\\d{5})","$1 $2 $3",["[67]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,
44091			,,[-1]],,,[,,,,,,,,,[-1]]],882:[,[,,"[13]\\d{6,11}",,,,,,,[7,8,9,10,11,12]],[,,,,,,,,,[-1]],[,,"3(?:2\\d{3}|37\\d{2}|4(?:2|7\\d{3}))\\d{4}",,,,"3421234",,,[7,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"1(?:3(?:0[0347]|[13][0139]|2[035]|4[013568]|6[0459]|7[06]|8[15678]|9[0689])\\d{4}|6\\d{5,10})|3(?:45|9\\d{3})\\d{7}",,,,"390123456789"],"001",882,,,,,,,,,[[,"(\\d{2})(\\d{4})(\\d{3})","$1 $2 $3",["3[23]"]],[,"(\\d{2})(\\d{5})","$1 $2",["16|342"]],[,"(\\d{2})(\\d{4})(\\d{4})",
44092			"$1 $2 $3",["34[57]"]],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["348"]],[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",["1"]],[,"(\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["16"]],[,"(\\d{2})(\\d{4,5})(\\d{5})","$1 $2 $3",["16|39"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,"348[57]\\d{7}",,,,"34851234567",,,[11]]],883:[,[,,"51\\d{7}(?:\\d{3})?",,,,,,,[9,12]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"51(?:00\\d{5}
vendor: 6,094 bytes, lines 44092-44120
44092(?:\\d{3})?|[13]0\\d{8})",
44093			,,,"510012345"],"001",883,,,,,,,,1,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["510"]],[,"(\\d{3})(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["510"]],[,"(\\d{4})(\\d{4})(\\d{4})","$1 $2 $3",["51[13]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],888:[,[,,"\\d{11}",,,,,,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",888,,,,,,,,1,[[,"(\\d{3})(\\d{3})(\\d{5})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,
44094			,[-1]],[,,"\\d{11}",,,,"12345678901"],,,[,,,,,,,,,[-1]]],979:[,[,,"\\d{9}",,,,,,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"\\d{9}",,,,"123456789"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",979,,,,,,,,1,[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]]};/*
44095
44096 Copyright (C) 2010 The Libphonenumber Authors.
44097
44098 Licensed under the Apache License, Version 2.0 (the "License");
44099 you may not use this file except in compliance with the License.
44100 You may obtain a copy of the License at
44101
44102 http://www.apache.org/licenses/LICENSE-2.0
44103
44104 Unless required by applicable law or agreed to in writing, software
44105 distributed under the License is distributed on an "AS IS" BASIS,
44106 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44107 See the License for the specific language governing permissions and
44108 limitations under the License.
44109*/
44110	function Q(){this.a={}}Q.a=function(){return Q.b?Q.b:Q.b=new Q};
44111	var ya={0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9","\uff10":"0","\uff11":"1","\uff12":"2","\uff13":"3","\uff14":"4","\uff15":"5","\uff16":"6","\uff17":"7","\uff18":"8","\uff19":"9","\u0660":"0","\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u06f0":"0","\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9"},Aa={0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",
44112		7:"7",8:"8",9:"9","\uff10":"0","\uff11":"1","\uff12":"2","\uff13":"3","\uff14":"4","\uff15":"5","\uff16":"6","\uff17":"7","\uff18":"8","\uff19":"9","\u0660":"0","\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u06f0":"0","\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9",A:"2",B:"2",C:"2",D:"3",E:"3",F:"3",G:"4",H:"4",I:"4",J:"5",K:"5",L:"5",M:"6",N:"6",O:"6",P:"7",
44113		Q:"7",R:"7",S:"7",T:"8",U:"8",V:"8",W:"9",X:"9",Y:"9",Z:"9"},R=RegExp("^[+\uff0b]+"),Ba=RegExp("([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9])"),Ca=RegExp("[+\uff0b0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]"),Da=/[\\\/] *x/,Ea=RegExp("[^0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9A-Za-z#]+$"),Fa=/(?:.*?[A-Za-z]){3}.*/,Ga=RegExp("(?:;ext=([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})|[ \u00a0\\t,]*(?:e?xt(?:ensi(?:o\u0301?|\u00f3))?n?|\uff45?\uff58\uff54\uff4e?|[;,x\uff58#\uff03~\uff5e]|int|anexo|\uff49\uff4e\uff54)[:\\.\uff0e]?[ \u00a0\\t,-]*([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})#?|[- ]+([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,5})#)$",
44114		"i"),Ha=RegExp("^[0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{2}$|^[+\uff0b]*(?:[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e*]*[0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]){3,}[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e*A-Za-z0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]*(?:;ext=([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})|[ \u00a0\\t,]*(?:e?xt(?:ensi(?:o\u0301?|\u00f3))?n?|\uff45?\uff58\uff54\uff4e?|[;,x\uff58#\uff03~\uff5e]|int|anexo|\uff49\uff4e\uff54)[:\\.\uff0e]?[ \u00a0\\t,-]*([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})#?|[- ]+([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,5})#)?$",
44115		"i"),Ia=/(\$\d)/;function Ja(a){var b=a.search(Ca);0<=b?(a=a.substring(b),a=a.replace(Ea,""),b=a.search(Da),0<=b&&(a=a.substring(0,b))):a="";return a}function Ka(a){return 2>a.length?!1:S(Ha,a)}function La(a){return S(Fa,a)?Ma(a,Aa):Ma(a,ya)}function Na(a){var b=La(a.toString());a.b="";a.a(b)}function Oa(a){return!!a&&(1!=G(a,9)||-1!=D(a,9)[0])}function Ma(a,b){for(var c=new K,d,e=a.length,f=0;f<e;++f)d=a.charAt(f),d=b[d.toUpperCase()],null!=d&&c.a(d);return c.toString()}
44116	function Pa(a){return null!=a&&isNaN(a)&&a.toUpperCase()in xa}
44117	function Qa(a,b,c){if(0==B(b,2)&&null!=b.a[5]){var d=F(b,5);if(0<d.length)return d}var d=F(b,1),e=T(b);if(0==c)return Ra(d,0,e,"");if(!(d in P))return e;a=U(a,d,Sa(d));b=null!=b.a[3]&&B(b,3).length?3==c?";ext="+B(b,3):null!=a.a[13]?B(a,13)+F(b,3):" ext. "+F(b,3):"";a:{a=D(a,20).length&&2!=c?D(a,20):D(a,19);for(var f,g=a.length,h=0;h<g;++h){f=a[h];var k=G(f,3);if(!k||!e.search(B(f,3,k-1)))if(k=new RegExp(B(f,1)),S(k,e)){a=f;break a}}a=null}a&&(g=a,a=F(g,2),f=new RegExp(B(g,1)),F(g,5),g=F(g,4),e=2==
44118	c&&null!=g&&0<g.length?e.replace(f,a.replace(Ia,g)):e.replace(f,a),3==c&&(e=e.replace(RegExp("^[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e]+"),""),e=e.replace(RegExp("[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e]+","g"),"-")));return Ra(d,c,e,b)}function U(a,b,c){return"001"==c?V(a,""+b):V(a,c)}
44119	function T(a){if(null==a.a[2])return"";var b=""+B(a,2);return null!=a.a[4]&&B(a,4)&&0<F(a,8)?Array(F(a,8)+1).join("0")+b:b}function Ra(a,b,c,d){switch(b){case 0:return"+"+a+c+d;case 1:return"+"+a+" "+c+d;case 3:return"tel:+"+a+"-"+c+d;default:return c+d}}
44120	function W(a,b){switch(b){case 4:return B(a,5);case 3:return B(a,4);case 1:return B(a,3);case 0:case 2:return B(a,2);case 5:return B(a,6);case 6:return B(a,8);case 7:return B(a,7);case 8:return B(a,21);case 9:return B(a,25);case 10:return B(a,28);default:return B(a,1)}}function Ta(a,b){return X(a,B(b,1))?X(a,B(b,5))?4:X(a,B(b,4))?3:X(a,B(b,6)
44120)?5:X(a,B(b,8))?6:X(a,B(b,7))?7:X(a,B(b,21))?8:X(a,B(b,25))?9:X(a,B(b,28))?10:X(a,B(b,2))?B(b,18)||X(a,B(b,3))?2:0:!B(b,18)&&X(a,B(b,3))?1:-1:-1}
44121	function V(a,b){if(null==b)return null;b=b.toUpperCase();var c=a.a[b];if(!c){c=xa[b];if(!c)return null;c=(new ra).b(N.f(),c);a.a[b]=c}return c}function X(a,b){var c=a.length;return 0<G(b,9)&&-1==x(D(b,9),c)?!1:S(F(b,2),a)}function Ua(a,b){if(!b)return null;var c=F(b,1);if(c=P[c])if(1==c.length)c=c[0];else a:{for(var d=T(b),e,f=c.length,g=0;g<f;g++){e=c[g];var h=V(a,e);if(null!=h.a[23]){if(!d.search(B(h,23))){c=e;break a}}else if(-1!=Ta(d,h)){c=e;break a}}c=null}else c=null;return c}
44122	function Sa(a){return(a=P[a])?a[0]:"ZZ"}function Y(a,b,c,d){var e=W(c,d),f=G(e,9)?D(e,9):D(B(c,1),9),e=D(e,10);if(2==d)if(Oa(W(c,0)))a=W(c,1),Oa(a)&&(f=f.concat(G(a,9)?D(a,9):D(B(c,1),9)),y(f),e.length?(e=e.concat(D(a,10)),y(e)):e=D(a,10));else return Y(a,b,c,1);if(-1==f[0])return 5;b=b.length;if(-1<x(e,b))return 4;c=f[0];return c==b?0:c>b?2:f[f.length-1]<b?3:-1<x(f,b,1)?0:5}
44123	function Va(a,b,c,d,e,f){if(!b.length)return 0;b=new K(b);var g;c&&(g=B(c,11));null==g&&(g="NonMatch");var h=b.toString();if(h.length)if(R.test(h))h=h.replace(R,""),b.b="",b.a(La(h)),g=1;else{h=new RegExp(g);Na(b);g=b.toString();if(g.search(h))g=!1;else{var h=g.match(h)[0].length,k=g.substring(h).match(Ba);k&&null!=k[1]&&0<k[1].length&&"0"==Ma(k[1],ya)?g=!1:(b.b="",b.a(g.substring(h)),g=!0)}g=g?5:20}else g=20;e&&C(f,6,g);if(20!=g){if(2>=b.b.length)throw Error("Phone number too short after IDD");a:{a=
44124		b.toString();if(a.length&&"0"!=a.charAt(0))for(e=a.length,b=1;3>=b&&b<=e;++b)if(c=parseInt(a.substring(0,b),10),c in P){d.a(a.substring(b));d=c;break a}d=0}if(d)return C(f,1,d),d;throw Error("Invalid country calling code");}if(c&&(g=F(c,10),h=""+g,k=b.toString(),!k.lastIndexOf(h,0)&&(h=new K(k.substring(h.length)),k=B(c,1),k=new RegExp(F(k,2)),Wa(h,c,null),h=h.toString(),!S(k,b.toString())&&S(k,h)||3==Y(a,b.toString(),c,-1))))return d.a(h),e&&C(f,6,10),C(f,1,g),g;C(f,1,0);return 0}
44125	function Wa(a,b,c){var d=a.toString(),e=d.length,f=B(b,15);if(e&&null!=f&&f.length){var g=new RegExp("^(?:"+f+")");if(e=g.exec(d)){var f=new RegExp(F(B(b,1),2)),h=S(f,d),k=e.length-1;b=B(b,16);if(null!=b&&b.length&&null!=e[k]&&e[k].length){if(d=d.replace(g,b),!h||S(f,d))c&&0<k&&c.a(e[1]),a.set(d)}else if(!h||S(f,d.substring(e[0].length)))c&&0<k&&null!=e[k]&&c.a(e[1]),a.set(d.substring(e[0].length))}}}
44126	function Z(a,b,c){if(!Pa(c)&&0<b.length&&"+"!=b.charAt(0))throw Error("Invalid country calling code");return Xa(a,b,c,!0)}
44127	function Xa(a,b,c,d){if(null==b)throw Error("The string supplied did not seem to be a phone number");if(250<b.length)throw Error("The string supplied is too long to be a phone number");var e=new K,f=b.indexOf(";phone-context=");if(0<=f){var g=f+15;if("+"==b.charAt(g)){var h=b.indexOf(";",g);0<h?e.a(b.substring(g,h)):e.a(b.substring(g))}g=b.indexOf("tel:");e.a(b.substring(0<=g?g+4:0,f))}else e.a(Ja(b));f=e.toString();g=f.indexOf(";isub=");0<g&&(e.b="",e.a(f.substring(0,g)));if(!Ka(e.toString()))throw Error("The string supplied did not seem to be a phone number");
44128		f=e.toString();if(!(Pa(c)||null!=f&&0<f.length&&R.test(f)))throw Error("Invalid country calling code");f=new O;d&&C(f,5,b);a:{b=e.toString();g=b.search(Ga);if(0<=g&&Ka(b.substring(0,g)))for(var h=b.match(Ga),k=h.length,q=1;q<k;++q)if(null!=h[q]&&0<h[q].length){e.b="";e.a(b.substring(0,g));b=h[q];break a}b=""}0<b.length&&C(f,3,b);g=V(a,c);b=new K;h=0;k=e.toString();try{h=Va(a,k,g,b,d,f)}catch(z){if("Invalid country calling code"==z.message&&R.test(k)){if(k=k.replace(R,""),h=Va(a,k,g,b,d,f),!h)throw z;
44129		}else throw z;}h?(e=Sa(h),e!=c&&(g=U(a,h,e))):(Na(e),b.a(e.toString()),null!=c?(h=F(g,10),C(f,1,h)):d&&(delete f.a[6],f.b&&delete f.b[6]));if(2>b.b.length)throw Error("The string supplied is too short to be a phone number");g&&(c=new K,e=new K(b.toString()),Wa(e,g,c),a=Y(a,e.toString(),g,-1),2!=a&&4!=a&&5!=a&&(b=e,d&&0<c.toString().length&&C(f,7,c.toString())));d=b.toString();a=d.length;if(2>a)throw Error("The string supplied is too short to be a phone number");if(17<a)throw Error("The string supplied is too long to be a phone number");
44130		if(1<d.length&&"0"==d.charAt(0)){C(f,4,!0);for(a=1;a<d.length-1&&"0"==d.charAt(a);)a++;1!=a&&C(f,8,a)}C(f,2,parseInt(d,10));return f}function S(a,b){var c="string"==typeof a?b.match("^(?:"+a+")$"):b.match(a);return c&&c[0].length==b.length?!0:!1};v("intlTelInputUtils",{});v("intlTelInputUtils.formatNumber",function(a,b,c){try{var d=Q.a(),e=Z(d,a,b);return Qa(d,e,"undefined"==typeof c?0:c)}catch(f){return a}});v("intlTelInputUtils.getExampleNumber",function(a,b,c){try{var d=Q.a(),e;a:{if(Pa(a)){var f=W(V(d,a),c);try{if(null!=f.a[6]){var g=B(f,6);e=Xa(d,g,a,!1);break a}}catch(h){}}e=null}return Qa(d,e,b?2:1)}catch(h){return""}});v("intlTelInputUtils.getExtension",function(a,b){try{return B(Z(Q.a(),a,b),3)}catch(c){return""}});
44131	v("intlTelInputUtils.getNumberType",function(a,b){try{var c=Q.a(),d;var e=Z(c,a,b),f=Ua(c,e),g=U(c,F(e,1),f);if(g){var h=T(e);d=Ta(h,g)}else d=-1;return d}catch(k){return-99}});
44132	v("intlTelInputUtils.getValidationError",function(a,b){try{var c=Q.a(),d;var e=Z(c,a,b),f=T(e),g=F(e,1);
44132if(g in P){var h=U(c,g,Sa(g));d=Y(c,f,h,-1)}else d=1;return d}catch(k){return"Invalid country calling code"==k.message?1:"The string supplied did not seem to be a phone number"==k.message?4:"Phone number too short after IDD"==k.message||"The string supplied is too short to be a phone number"==k?2:"The string supplied is too long to be a phone number"==k.message?3:-99}});
44133	v("intlTelInputUtils.isValidNumber",function(a,b){try{var c=Q.a(),d=Z(c,a,b),e;var f=Ua(c,d),g=F(d,1),h=U(c,g,f),k;if(!(k=!h)){var q;if(q="001"!=f){var z,za=V(c,f);if(!za)throw Error("Invalid region code: "+f);z=F(za,10);q=g!=z}k=q}if(k)e=!1;else{var Ya=T(d);e=-1!=Ta(Ya,h)}return e}catch(Za){return!1}});v("intlTelInputUtils.numberFormat",{E164:0,INTERNATIONAL:1,NATIONAL:2,RFC3966:3});
44134	v("intlTelInputUtils.numberType",{FIXED_LINE:0,MOBILE:1,FIXED_LINE_OR_MOBILE:2,TOLL_FREE:3,PREMIUM_RATE:4,SHARED_COST:5,VOIP:6,PERSONAL_NUMBER:7,PAGER:8,UAN:9,VOICEMAIL:10,UNKNOWN:-1});v("intlTelInputUtils.validationError",{IS_POSSIBLE:0,INVALID_COUNTRY_CODE:1,TOO_SHORT:2,TOO_LONG:3,NOT_A_NUMBER:4});})();
44135
44136/**
44137 * WHMCS Telephone Country Code Dropdown
44138 *
44139 * Using https://github.com/jackocnr/intl-tel-input
44140 *
44141 * @copyright Copyright (c) WHMCS Limited 2005-2019
44142 * @license https://www.whmcs.com/license/ WHMCS Eula
44143 */
44144
44145jQuery(document).ready(function() {
44146	if (typeof customCountryData !== "undefined") {
44147		var teleCountryData = $.fn['intlTelInput'].getCountryData();
44148		for (var code in customCountryData) {
44149			if (customCountryData.hasOwnProperty(code)) {
44150				var countryDetails = customCountryData[code];
44151				codeLower = code.toLowerCase();
44152				if (countryDetails === false) {
44153					for (var i = 0; i < teleCountryData.length; i++) {
44154						if (codeLower === teleCountryData[i].iso2) {
44155							teleCountryData.splice(i, 1);
44156							break;
44157						}
44158					}
44159				} else {
44160					teleCountryData.push(
44161						{
44162							name: countryDetails.name,
44163							iso2: codeLower,
44164							dialCode: countryDetails.callingCode,
44165							priority: 0,
44166							areaCodes: null
44167						}
44168					);
44169				}
44170			}
44171		}
44172	}
44173
44174	if (jQuery('body').data('phone-cc-input')) {
44175		var phoneInput = jQuery('input[name^="phone"], input[name$="phone"], input[name="domaincontactphonenumber"]').not('input[type="hidden"]');
44176		if (phoneInput.length) {
44177			var countryInput = jQuery('[name^="country"], [name$="country"]'),
44178				initialCountry = 'us';
44179			if (countryInput.length) {
44180				initialCountry = countryInput.val().toLowerCase();
44181				if (initialCountry === 'um') {
44182					initialCountry = 'us';
44183				}
44184			}
44185
44186			phoneInput.each(function(){
44187				var thisInput = jQuery(this),
44188					inputName = thisInput.attr('name');
44189				if (inputName === 'domaincontactphonenumber') {
44190					initialCountry = jQuery('[name="domaincontactcountry"]').val().toLowerCase();
44191				}
44192				jQuery(this).before(
44193					'<input id="populatedCountryCode' + inputName + '" type="hidden" name="country-calling-code-' + inputName + '" value="" />'
44194				);
44195				thisInput.intlTelInput({
44196					preferredCountries: [initialCountry, "us", "gb"].filter(function(value, index, self) {
44197						return self.indexOf(value) === index;
44198					}),
44199					initialCountry: initialCountry,
44200					autoPlaceholder: 'polite', //always show the helper placeholder
44201					separateDialCode: true
44202				});
44203
44204				thisInput.on('countrychange', function (e, countryData) {
44205					jQuery('#populatedCountryCode' + inputName).val(countryData.dialCode);
44206					if (jQuery(this).val() === '+' + countryData.dialCode) {
44207						jQuery(this).val('');
44208					}
44209				});
44210				thisInput.on('blur keydown', function (e) {
44211					if (e.type === 'blur' || (e.type === 'keydown' && e.keyCode === 13)) {
44212						var number = jQuery(this).intlTelInput("getNumber"),
44213							countryData = jQuery(this).intlTelInput("getSelectedCountryData"),
44214							countryPrefix = '+' + countryData.dialCode;
44215
44216						if (number.indexOf(countryPrefix) === 0 && (number.match(/\+/g) || []).length > 1) {
44217							number = number.substr(countryPrefix.length);
44218						}
44219						jQuery(this).intlTelInput("setNumber", number);
44220					}
44221				});
44222				jQuery('#populatedCountryCode' + inputName).val(thisInput.intlTelInput('getSelectedCountryData').dialCode);
44223
44224				countryInput.on('change', function() {
44225					if (thisInput.val() === '') {
44226						var country = jQuery(this).val().toLowerCase();
44227						if (country === 'um') {
44228							country = 'us';
44229						}
44230						phoneInput.intlTelInput('setCountry', country);
44231					}
44232				});
44233
44234				// this must be .attr (not .data) in order for it to be found by [data-initial-value] selector
44235				thisInput.attr('data-initial-value', $(thisInput).val());
44236
44237				thisInput.parents('form').find('input[type=reset]').each(function() {
44238					var resetButton = this;
44239					var form = $(resetButton).parents('form');
44240
44241					if (!$(resetButton).data('phone-handler')) {
44242						$(resetButton).data('phone-handler', true);
44243
44244						$(resetButton).click(function(e) {
44245							e.stopPropagation();
44246
44247							$(form).trigger('reset');
44248
44249							$(form).find('input[data-initial-value]').each(function() {
44250								var inputToReset = this;
44251
44252								$(inputToReset).val(
44253									$(inputToReset).attr('data-initial-value')
44254								);
44255							});
44256
44257							return false;
44258						});
44259					}
44260				});
44261			});
44262
44263			/**
44264			 * In places where a form icon is present, hide it.
44265			 * Where the input has a class of field, remove that and add form-control in place.
44266			 */
44267			phoneInput.parents('div.form-group').find('.field-icon').hide().end();
44268			phoneInput.removeClass('field').addClass('form-control');
44269		}
44270
44271		var registrarPhoneInput = jQuery('input[name$="][Phone Number]"], input[name$="][Phone]"]').not('input[type="hidden"]');
44272		if (registrarPhoneInput.length) {
44273			jQuery.each(registrarPhoneInput, function(index, input) {
44274				var thisInput = jQuery(this),
44275					inputName = thisInput.attr('name');
44276				inputName = inputName.replace('contactdetails[', '').replace('][Phone Number]', '').replace('][Phone]', '');
44277
44278				var countryInput = jQuery('[name$="' + inputName + '][Country]"]'),
44279					initialCountry = countryInput.val().toLowerCase();
44280				if (initialCountry === 'um') {
44281					initialCountry = 'us';
44282				}
44283
44284				thisInput.before('<input id="populated' + inputName + 'CountryCode" class="' + inputName + 'customwhois" type="hidden" name="contactdetails[' + inputName + '][Phone Country Code]" value="" />');
44285				thisInput.intlTelInput({
44286					preferredCountries: [initialCountry, "us", "gb"].filter(function(value, index, self) {
44287						return self.indexOf(value) === index;
44288					}),
44289					initialCountry: initialCountry,
44290					autoPlaceholder: 'polite', //always show the helper placeholder
44291					separateDialCode: true
44292				});
44293
44294				thisInput.on('countrychange', function (e, countryData) {
44295					jQuery('#populated' + inputName + 'CountryCode').val(countryData.dialCode);
44296					if (jQuery(this).val() === '+' + countryData.dialCode) {
44297						jQuery(this).val('');
44298					}
44299				});
44300				thisInput.on('blur keydown', function (e) {
44301					if (e.type === 'blur' || (e.type === 'keydown' && e.keyCode === 13)) {
44302						var number = jQuery(this).intlTelInput("getNumber"),
44303							countryData = jQuery(this).intlTelInput("getSelectedCountryData"),
44304							countryPrefix = '+' + countryData.dialCode;
44305
44306						if (number.indexOf(countryPrefix) === 0 && (number.match(/\+/g) || []).length > 1) {
44307							number = number.substr(countryPrefix.length);
44308						}
44309						jQuery(this).intlTelInput("setNumber", number);
44310					}
44311				});
44312				jQuery('#populated' + inputName + 'CountryCode').val(thisInput.intlTelInput('getSelectedCountryData').dialCode);
44313
44314				countryInput.on('blur', function() {
44315					if (thisInput.val() === '') {
44316						var country = jQuery(this).val().toLowerCase();
44317						if (country === 'um') {
44318							country = 'us';
44319						}
44320						thisInput.intlTelInput('setCountry', country);
44321					}
44322				});
44323
44324			});
44325		}
44326	}
44327});
44328
44329/*!
44330 * Lightbox v2.8.1
44331 * by Lokesh Dhakar
44332 *
44333 * More info:
44334 * http://lokeshdhakar.com/projects/lightbox2/
44335 *
44336 * Copyright 2007, 2015 Lokesh Dhakar
44337 * Released under the MIT license
44338 * https://github.com/lokesh/lightbox2/blob/master/LICENSE
44339 */
44340
44341// Uses Node, AMD or browser globals to create a module.
44342(function (root, factory) {
44343	if (typeof define === 'function' && define.amd) {
44344		// AMD. Register as an anonymous module.
44345		define(['jquery'], factory);
44346	} else if (typeof exports === 'object') {
44347		// Node. Does not work with strict CommonJS, but
44348		// only CommonJS-like environments that support module.exports,
44349		// like Node.
44350		module.exports = factory(require('jquery'));
44351	} else {
44352		// Browser globals (root is window)
44353		root.lightbox = factory(root.jQuery);
44354	}
44355}(this, function ($) {
44356
44357	function Lightbox(options) {
44358		this.album = [];
44359		this.currentImageIndex = void 0;
44360		this.init();
44361
44362		// options
44363		this.options = $.extend({}, this.constructor.defaults);
44364		this.option(options);
44365	}
44366
44367	// Descriptions of all options available on the demo site:
44368	// http://lokeshdhakar.com/projects/lightbox2/index.html#options
44369	Lightbox.defaults = {
44370		albumLabel: 'Image %1 of %2',
44371		alwaysShowNavOnTouchDevices: false,
44372		fadeDuration: 500,
44373		fitImagesInViewport: true,
44374		// maxWidth: 800,
44375		// maxHeight: 600,
44376		positionFromTop: 50,
44377		resizeDuration: 700,
44378		showImageNumberLabel: true,
44379		wrapAround: false
44380	};
44381
44382	Lightbox.prototype.option = function(options) {
44383		$.extend(this.options, options);
44384	};
44385
44386	Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {
44387		return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);
44388	};
44389
44390	Lightbox.prototype.init = function() {
44391		this.enable();
44392		this.build();
44393	};
44394
44395	// Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
44396	// that contain 'lightbox'. When these are clicked, start lightbox.
44397	Lightbox.prototype.enable = function() {
44398		var self = this;
44399		$('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {
44400			self.start($(event.currentTarget));
44401			return false;
44402		});
44403	};
44404
44405	// Build html for the lightbox and the overlay.
44406	// Attach event handlers to the new DOM elements. click click click
44407	Lightbox.prototype.build = function() {
44408		var self = this;
44409		$('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav"><a class="lb-prev" href="" ></a><a class="lb-next" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo($('body'));
44410
44411		// Cache jQuery objects
44412		this.$lightbox       = $('#lightbox');
44413		this.$overlay        = $('#lightboxOverlay');
44414		this.$outerContainer = this.$lightbox.find('.lb-outerContainer');
44415		this.$container      = this.$lightbox.find('.lb-container');
44416
44417		// Store css values for future lookup
44418		this.containerTopPadding = parseInt(this.$container.css('padding-top'), 10);
44419		this.containerRightPadding = parseInt(this.$container.css('padding-right'), 10);
44420		this.containerBottomPadding = parseInt(this.$container.css('padding-bottom'), 10);
44421		this.containerLeftPadding = parseInt(this.$container.css('padding-left'), 10);
44422
44423		// Attach event handlers to the newly minted DOM elements
44424		this.$overlay.hide().on('click', function() {
44425			self.end();
44426			return false;
44427		});
44428
44429		this.$lightbox.hide().on('click', function(event) {
44430			if ($(event.target).attr('id') === 'lightbox') {
44431				self.end();
44432			}
44433			return false;
44434		});
44435
44436		this.$outerContainer.on('click', function(event) {
44437			if ($(event.target).attr('id') === 'lightbox') {
44438				self.end();
44439			}
44440			return false;
44441		});
44442
44443		this.$lightbox.find('.lb-prev').on('click', function() {
44444			if (self.currentImageIndex === 0) {
44445				self.changeImage(self.album.length - 1);
44446			} else {
44447				self.changeImage(self.currentImageIndex - 1);
44448			}
44449			return false;
44450		});
44451
44452		this.$lightbox.find('.lb-next').on('click', function() {
44453			if (self.currentImageIndex === self.album.length - 1) {
44454				self.changeImage(0);
44455			} else {
44456				self.changeImage(self.currentImageIndex + 1);
44457			}
44458			return false;
44459		});
44460
44461		this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {
44462			self.end();
44463			return false;
44464		});
44465	};
44466
44467	// Show overlay and lightbox. If the image is part of a set, add siblings to album array.
44468	Lightbox.prototype.start = function($link) {
44469		var self    = this;
44470		var $window = $(window);
44471
44472		$window.on('resize', $.proxy(this.sizeOverlay, this));
44473
44474		$('select, object, embed').css({
44475			visibility: 'hidden'
44476		});
44477
44478		this.sizeOverlay();
44479
44480		this.album = [];
44481		var imageNumber = 0;
44482
44483		function addToAlbum($link) {
44484			self.album.push({
44485				link: $link.attr('href'),
44486				title: $link.attr('data-title') || $link.attr('title')
44487			});
44488		}
44489
44490		// Support both data-lightbox attribute and rel attribute implementations
44491		var dataLightboxValue = $link.attr('data-lightbox');
44492		var $links;
44493
44494		if (dataLightboxValue) {
44495			$links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]');
44496			for (var i = 0; i < $links.length; i = ++i) {
44497				addToAlbum($($links[i]));
44498				if ($links[i] === $link[0]) {
44499					imageNumber = i;
44500				}
44501			}
44502		} else {
44503			if ($link.attr('rel') === 'lightbox') {
44504				// If image is not part of a set
44505				addToAlbum($link);
44506			} else {
44507				// If image is part of a set
44508				$links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
44509				for (var j = 0; j < $links.length; j = ++j) {
44510					addToAlbum($($links[j]));
44511					if ($links[j] === $link[0]) {
44512						imageNumber = j;
44513					}
44514				}
44515			}
44516		}
44517
44518		// Position Lightbox
44519		var top  = $window.scrollTop() + this.options.positionFromTop;
44520		var left = $window.scrollLeft();
44521		this.$lightbox.css({
44522			top: top + 'px',
44523			left: left + 'px'
44524		}).fadeIn(this.options.fadeDuration);
44525
44526		this.changeImage(imageNumber);
44527	};
44528
44529	// Hide most UI elements in preparation for the animated resizing of the lightbox.
44530	Lightbox.prototype.changeImage = function(imageNumber) {
44531		var self = this;
44532
44533		this.disableKeyboardNav();
44534		var $image = this.$lightbox.find('.lb-image');
44535
44536		this.$overlay.fadeIn(this.options.fadeDuration);
44537
44538		$('.lb-loader').fadeIn('slow');
44539		this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();
44540
44541		this.$outerContainer.addClass('animating');
44542
44543		// When image to show is preloaded, we send the width and height to sizeContainer()
44544		var preloader = new Image();
44545		preloader.onload = function() {
44546			var $preloader;
44547			var imageHeight;
44548			var imageWidth;
44549			var maxImageHeight;
44550			var maxImageWidth;
44551			var windowHeight;
44552			var windowWidth;
44553
44554			$image.attr('src', self.album[imageNumber].link);
44555
44556			$preloader = $(preloader);
44557
44558			$image.width(preloader.width);
44559			$image.height(preloader.height);
44560
44561			if (self.options.fitImagesInViewport) {
44562				// Fit image inside the viewport.
44563				// Take into account the border around the image and an additional 10px gutter on each side.
44564
44565				windowWidth    = $(window).width();
44566				windowHeight   = $(window).height();
44567				maxImageWidth  = windowWidth - self.containerLeftPadding - self.containerRightPadding - 20;
44568				maxImageHeight = windowHeight - self.containerTopPadding - self.containerBottomPadding - 120;
44569
44570				// Check if image size is larger then maxWidth|maxHeight in settings
44571				if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {
44572					maxImageWidth = self.options.maxWidth;
44573				}
44574				if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {
44575					maxImageHeight = self.options.maxHeight;
44576				}
44577
44578				// Is there a fitting issue?
44579				if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {
44580					if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {
44581						imageWidth  = maxImageWidth;
44582						imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);
44583						$image.width(imageWidth);
44584						$image.height(imageHeight);
44585					} else {
44586						imageHeight = maxImageHeight;
44587						imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);
44588						$image.width(imageWidth);
44589						$image.height(imageHeight);
44590					}
44591				}
44592			}
44593			self.sizeContainer($image.width(), $image.height());
44594		};
44595
44596		preloader.src          = this.album[imageNumber].link;
44597		this.currentImageIndex = imageNumber;
44598	};
44599
44600	// Stretch overlay to fit the viewport
44601	Lightbox.prototype.sizeOverlay = function() {
44602		this.$overlay
44603			.width($(window).width())
44604			.height($(document).height());
44605	};
44606
44607	// Animate the size of the lightbox to fit the image we are showing
44608	Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
44609		var self = this;
44610
44611		var oldWidth  = this.$outerContainer.outerWidth();
44612		var oldHeight = this.$outerContainer.outerHeight();
44613		var newWidth  = imageWidth + this.containerLeftPadding + this.containerRightPadding;
44614		var newHeight = imageHeight + this.containerTopPadding + this.containerBottomPadding;
44615
44616		function postResize() {
44617			self.$lightbox.find('.lb-dataContainer').width(newWidth);
44618			self.$lightbox.find('.lb-prevLink').height(newHeight);
44619			self.$lightbox.find('.lb-nextLink').height(newHeight);
44620			self.showImage();
44621		}
44622
44623		if (oldWidth !== newWidth || oldHeight !== newHeight) {
44624			this.$outerContainer.animate({
44625				width: newWidth,
44626				height: newHeight
44627			}, this.options.resizeDuration, 'swing', function() {
44628				postResize();
44629			});
44630		} else {
44631			postResize();
44632		}
44633	};
44634
44635	// Display the image and its details and begin preload neighboring images.
44636	Lightbox.prototype.showImage = function() {
44637		this.$lightbox.find('.lb-loader').stop(true).hide();
44638		this.$lightbox.find('.lb-image').fadeIn('slow');
44639
44640		this.updateNav();
44641		this.updateDetails();
44642		this.preloadNeighboringImages();
44643		this.enableKeyboardNav();
44644	};
44645
44646	// Display previous and next navigation if appropriate.
44647	Lightbox.prototype.updateNav = function() {
44648		// Check to see if the browser supports touch events. If so, we take the conservative approach
44649		// and assume that mouse hover events are not supported and always show prev/next navigation
44650		// arrows in image sets.
44651		var alwaysShowNav = false;
44652		try {
44653			document.createEvent('TouchEvent');
44654			alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;
44655		} catch (e) {}
44656
44657		this.$lightbox.find('.lb-nav').show();
44658
44659		if (this.album.length > 1) {
44660			if (this.options.wrapAround) {
44661				if (alwaysShowNav) {
44662					this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');
44663				}
44664				this.$lightbox.find('.lb-prev, .lb-next').show();
44665			} else {
44666				if (this.currentImageIndex > 0) {
44667					this.$lightbox.find('.lb-prev').show();
44668					if (alwaysShowNav) {
44669						this.$lightbox.find('.lb-prev').css('opacity', '1');
44670					}
44671				}
44672				if (this.currentImageIndex < this.album.length - 1) {
44673					this.$lightbox.find('.lb-next').show();
44674					if (alwaysShowNav) {
44675						this.$lightbox.find('.lb-next').css('opacity', '1');
44676					}
44677				}
44678			}
44679		}
44680	};
44681
44682	// Display caption, image number, and closing button.
44683	Lightbox.prototype.updateDetails = function() {
44684		var self = this;
44685
44686		// Enable anchor clicks in the injected caption html.
44687		// Thanks Nate Wright for the fix. @https://github.com/NateWr
44688		if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&
44689			this.album[this.currentImageIndex].title !== '') {
44690			this.$lightbox.find('.lb-caption')
44691				.html(this.album[this.currentImageIndex].title)
44692				.fadeIn('fast')
44693				.find('a').on('click', function(event) {
44694				if ($(this).attr('target') !== undefined) {
44695					window.open($(this).attr('href'), $(this).attr('target'));
44696				} else {
44697					location.href = $(this).attr('href');
44698				}
44699			});
44700		}
44701
44702		if (this.album.length > 1 && this.options.showImageNumberLabel) {
44703			var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
44704			this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');
44705		} else {
44706			this.$lightbox.find('.lb-number').hide();
44707		}
44708
44709		this.$outerContainer.removeClass('animating');
44710
44711		this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
44712			return self.sizeOverlay();
44713		});
44714	};
44715
44716	// Preload previous and next images in set.
44717	Lightbox.prototype.preloadNeighboringImages = function() {
44718		if (this.album.length > this.currentImageIndex + 1) {
44719			var preloadNext = new Image();
44720			preloadNext.src = this.album[this.currentImageIndex + 1].link;
44721		}
44722		if (this.currentImageIndex > 0) {
44723			var preloadPrev = new Image();
44724			preloadPrev.src = this.album[this.currentImageIndex - 1].link;
44725		}
44726	};
44727
44728	Lightbox.prototype.enableKeyboardNav = function() {
44729		$(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));
44730	};
44731
44732	Lightbox.prototype.disableKeyboardNav = function() {
44733		$(document).off('.keyboard');
44734	};
44735
44736	Lightbox.prototype.keyboardAction = function(event) {
44737		var KEYCODE_ESC        = 27;
44738		var KEYCODE_LEFTARROW  = 37;
44739		var KEYCODE_RIGHTARROW = 39;
44740
44741		var keycode = event.keyCode;
44742		var key     = String.fromCharCode(keycode).toLowerCase();
44743		if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {
44744			this.end();
44745		} else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {
44746			if (this.currentImageIndex !== 0) {
44747				this.changeImage(this.currentImageIndex - 1);
44748			} else if (this.options.wrapAround && this.album.length > 1) {
44749				this.changeImage(this.album.length - 1);
44750			}
44751		} else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {
44752			if (this.currentImageIndex !== this.album.length - 1) {
44753				this.changeImage(this.currentImageIndex + 1);
44754			} else if (this.options.wrapAround && this.album.length > 1) {
44755				this.changeImage(0);
44756			}
44757		}
44758	};
44759
44760	// Closing time. :-(
44761	Lightbox.prototype.end = function() {
44762		this.disableKeyboardNav();
44763		$(window).off('resize', this.sizeOverlay);
44764		this.$lightbox.fadeOut(this.options.fadeDuration);
44765		this.$overlay.fadeOut(this.options.fadeDuration);
44766		$('select, object, embed').css({
44767			visibility: 'visible'
44768		});
44769	};
44770
44771	return new Lightbox();
44772}));
44773
44774// TinyColor v1.4.2
44775// https://github.com/bgrins/TinyColor
44776// Brian Grinstead, MIT License
44777
44778(function(Math) {
44779
44780	var trimLeft = /^\s+/,
44781		trimRight = /\s+$/,
44782		tinyCounter = 0,
44783		mathRound = Math.round,
44784		mathMin = Math.min,
44785		mathMax = Math.max,
44786		mathRandom = Math.random;
44787
44788	function tinycolor (color, opts) {
44789
vendor: 17,995 bytes, lines 44790-45411
44790		color = (color) ? color : '';
44791		opts = opts || { };
44792
44793		// If input is already a tinycolor, return itself
44794		if (color instanceof tinycolor) {
44795			return color;
44796		}
44797		// If we are called as a function, call using new instead
44798		if (!(this instanceof tinycolor)) {
44799			return new tinycolor(color, opts);
44800		}
44801
44802		var rgb = inputToRGB(color);
44803		this._originalInput = color,
44804			this._r = rgb.r,
44805			this._g = rgb.g,
44806			this._b = rgb.b,
44807			this._a = rgb.a,
44808			this._roundA = mathRound(100*this._a) / 100,
44809			this._format = opts.format || rgb.format;
44810		this._gradientType = opts.gradientType;
44811
44812		// Don't let the range of [0,255] come back in [0,1].
44813		// Potentially lose a little bit of precision here, but will fix issues where
44814		// .5 gets interpreted as half of the total, instead of half of 1
44815		// If it was supposed to be 128, this was already taken care of by `inputToRgb`
44816		if (this._r < 1) { this._r = mathRound(this._r); }
44817		if (this._g < 1) { this._g = mathRound(this._g); }
44818		if (this._b < 1) { this._b = mathRound(this._b); }
44819
44820		this._ok = rgb.ok;
44821		this._tc_id = tinyCounter++;
44822	}
44823
44824	tinycolor.prototype = {
44825		isDark: function() {
44826			return this.getBrightness() < 128;
44827		},
44828		isLight: function() {
44829			return !this.isDark();
44830		},
44831		isValid: function() {
44832			return this._ok;
44833		},
44834		getOriginalInput: function() {
44835			return this._originalInput;
44836		},
44837		getFormat: function() {
44838			return this._format;
44839		},
44840		getAlpha: function() {
44841			return this._a;
44842		},
44843		getBrightness: function() {
44844			//http://www.w3.org/TR/AERT#color-contrast
44845			var rgb = this.toRgb();
44846			return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
44847		},
44848		getLuminance: function() {
44849			//http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
44850			var rgb = this.toRgb();
44851			var RsRGB, GsRGB, BsRGB, R, G, B;
44852			RsRGB = rgb.r/255;
44853			GsRGB = rgb.g/255;
44854			BsRGB = rgb.b/255;
44855
44856			if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}
44857			if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}
44858			if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}
44859			return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);
44860		},
44861		setAlpha: function(value) {
44862			this._a = boundAlpha(value);
44863			this._roundA = mathRound(100*this._a) / 100;
44864			return this;
44865		},
44866		toHsv: function() {
44867			var hsv = rgbToHsv(this._r, this._g, this._b);
44868			return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
44869		},
44870		toHsvString: function() {
44871			var hsv = rgbToHsv(this._r, this._g, this._b);
44872			var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
44873			return (this._a == 1) ?
44874				"hsv("  + h + ", " + s + "%, " + v + "%)" :
44875				"hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
44876		},
44877		toHsl: function() {
44878			var hsl = rgbToHsl(this._r, this._g, this._b);
44879			return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
44880		},
44881		toHslString: function() {
44882			var hsl = rgbToHsl(this._r, this._g, this._b);
44883			var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
44884			return (this._a == 1) ?
44885				"hsl("  + h + ", " + s + "%, " + l + "%)" :
44886				"hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
44887		},
44888		toHex: function(allow3Char) {
44889			return rgbToHex(this._r, this._g, this._b, allow3Char);
44890		},
44891		toHexString: function(allow3Char) {
44892			return '#' + this.toHex(allow3Char);
44893		},
44894		toHex8: function(allow4Char) {
44895			return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
44896		},
44897		toHex8String: function(allow4Char) {
44898			return '#' + this.toHex8(allow4Char);
44899		},
44900		toRgb: function() {
44901			return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
44902		},
44903		toRgbString: function() {
44904			return (this._a == 1) ?
44905				"rgb("  + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
44906				"rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
44907		},
44908		toPercentageRgb: function() {
44909			return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
44910		},
44911		toPercentageRgbString: function() {
44912			return (this._a == 1) ?
44913				"rgb("  + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
44914				"rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
44915		},
44916		toName: function() {
44917			if (this._a === 0) {
44918				return "transparent";
44919			}
44920
44921			if (this._a < 1) {
44922				return false;
44923			}
44924
44925			return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
44926		},
44927		toFilter: function(secondColor) {
44928			var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);
44929			var secondHex8String = hex8String;
44930			var gradientType = this._gradientType ? "GradientType = 1, " : "";
44931
44932			if (secondColor) {
44933				var s = tinycolor(secondColor);
44934				secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);
44935			}
44936
44937			return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
44938		},
44939		toString: function(format) {
44940			var formatSet = !!format;
44941			format = format || this._format;
44942
44943			var formattedString = false;
44944			var hasAlpha = this._a < 1 && this._a >= 0;
44945			var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name");
44946
44947			if (needsAlphaFormat) {
44948				// Special case for "transparent", all other non-alpha formats
44949				// will return rgba when there is transparency.
44950				if (format === "name" && this._a === 0) {
44951					return this.toName();
44952				}
44953				return this.toRgbString();
44954			}
44955			if (format === "rgb") {
44956				formattedString = this.toRgbString();
44957			}
44958			if (format === "prgb") {
44959				formattedString = this.toPercentageRgbString();
44960			}
44961			if (format === "hex" || format === "hex6") {
44962				formattedString = this.toHexString();
44963			}
44964			if (format === "hex3") {
44965				formattedString = this.toHexString(true);
44966			}
44967			if (format === "hex4") {
44968				formattedString = this.toHex8String(true);
44969			}
44970			if (format === "hex8") {
44971				formattedString = this.toHex8String();
44972			}
44973			if (format === "name") {
44974				formattedString = this.toName();
44975			}
44976			if (format === "hsl") {
44977				formattedString = this.toHslString();
44978			}
44979			if (format === "hsv") {
44980				formattedString = this.toHsvString();
44981			}
44982
44983			return formattedString || this.toHexString();
44984		},
44985		clone: function() {
44986			return tinycolor(this.toString());
44987		},
44988
44989		_applyModification: function(fn, args) {
44990			var color = fn.apply(null, [this].concat([].slice.call(args)));
44991			this._r = color._r;
44992			this._g = color._g;
44993			this._b = color._b;
44994			this.setAlpha(color._a);
44995			return this;
44996		},
44997		lighten: function() {
44998			return this._applyModification(lighten, arguments);
44999		},
45000		brighten: function() {
45001			return this._applyModification(brighten, arguments);
45002		},
45003		darken: function() {
45004			return this._applyModification(darken, arguments);
45005		},
45006		desaturate: function() {
45007			return this._applyModification(desaturate, arguments);
45008		},
45009		saturate: function() {
45010			return this._applyModification(saturate, arguments);
45011		},
45012		greyscale: function() {
45013			return this._applyModification(greyscale, arguments);
45014		},
45015		spin: function() {
45016			return this._applyModification(spin, arguments);
45017		},
45018
45019		_applyCombination: function(fn, args) {
45020			return fn.apply(null, [this].concat([].slice.call(args)));
45021		},
45022		analogous: function() {
45023			return this._applyCombination(analogous, arguments);
45024		},
45025		complement: function() {
45026			return this._applyCombination(complement, arguments);
45027		},
45028		monochromatic: function() {
45029			return this._applyCombination(monochromatic, arguments);
45030		},
45031		splitcomplement: function() {
45032			return this._applyCombination(splitcomplement, arguments);
45033		},
45034		triad: function() {
45035			return this._applyCombination(triad, arguments);
45036		},
45037		tetrad: function() {
45038			return this._applyCombination(tetrad, arguments);
45039		}
45040	};
45041
45042// If input is an object, force 1 into "1.0" to handle ratios properly
45043// String input requires "1.0" as input, so 1 will be treated as 1
45044	tinycolor.fromRatio = function(color, opts) {
45045		if (typeof color == "object") {
45046			var newColor = {};
45047			for (var i in color) {
45048				if (color.hasOwnProperty(i)) {
45049					if (i === "a") {
45050						newColor[i] = color[i];
45051					}
45052					else {
45053						newColor[i] = convertToPercentage(color[i]);
45054					}
45055				}
45056			}
45057			color = newColor;
45058		}
45059
45060		return tinycolor(color, opts);
45061	};
45062
45063// Given a string or object, convert that input to RGB
45064// Possible string inputs:
45065//
45066//     "red"
45067//     "#f00" or "f00"
45068//     "#ff0000" or "ff0000"
45069//     "#ff000000" or "ff000000"
45070//     "rgb 255 0 0" or "rgb (255, 0, 0)"
45071//     "rgb 1.0 0 0" or "rgb (1, 0, 0)"
45072//     "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
45073//     "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
45074//     "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
45075//     "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
45076//     "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
45077//
45078	function inputToRGB(color) {
45079
45080		var rgb = { r: 0, g: 0, b: 0 };
45081		var a = 1;
45082		var s = null;
45083		var v = null;
45084		var l = null;
45085		var ok = false;
45086		var format = false;
45087
45088		if (typeof color == "string") {
45089			color = stringInputToObject(color);
45090		}
45091
45092		if (typeof color == "object") {
45093			if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
45094				rgb = rgbToRgb(color.r, color.g, color.b);
45095				ok = true;
45096				format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
45097			}
45098			else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
45099				s = convertToPercentage(color.s);
45100				v = convertToPercentage(color.v);
45101				rgb = hsvToRgb(color.h, s, v);
45102				ok = true;
45103				format = "hsv";
45104			}
45105			else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
45106				s = convertToPercentage(color.s);
45107				l = convertToPercentage(color.l);
45108				rgb = hslToRgb(color.h, s, l);
45109				ok = true;
45110				format = "hsl";
45111			}
45112
45113			if (color.hasOwnProperty("a")) {
45114				a = color.a;
45115			}
45116		}
45117
45118		a = boundAlpha(a);
45119
45120		return {
45121			ok: ok,
45122			format: color.format || format,
45123			r: mathMin(255, mathMax(rgb.r, 0)),
45124			g: mathMin(255, mathMax(rgb.g, 0)),
45125			b: mathMin(255, mathMax(rgb.b, 0)),
45126			a: a
45127		};
45128	}
45129
45130
45131// Conversion Functions
45132// --------------------
45133
45134// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
45135// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
45136
45137// `rgbToRgb`
45138// Handle bounds / percentage checking to conform to CSS color spec
45139// <http://www.w3.org/TR/css3-color/>
45140// *Assumes:* r, g, b in [0, 255] or [0, 1]
45141// *Returns:* { r, g, b } in [0, 255]
45142	function rgbToRgb(r, g, b){
45143		return {
45144			r: bound01(r, 255) * 255,
45145			g: bound01(g, 255) * 255,
45146			b: bound01(b, 255) * 255
45147		};
45148	}
45149
45150// `rgbToHsl`
45151// Converts an RGB color value to HSL.
45152// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
45153// *Returns:* { h, s, l } in [0,1]
45154	function rgbToHsl(r, g, b) {
45155
45156		r = bound01(r, 255);
45157		g = bound01(g, 255);
45158		b = bound01(b, 255);
45159
45160		var max = mathMax(r, g, b), min = mathMin(r, g, b);
45161		var h, s, l = (max + min) / 2;
45162
45163		if(max == min) {
45164			h = s = 0; // achromatic
45165		}
45166		else {
45167			var d = max - min;
45168			s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
45169			switch(max) {
45170				case r: h = (g - b) / d + (g < b ? 6 : 0); break;
45171				case g: h = (b - r) / d + 2; break;
45172				case b: h = (r - g) / d + 4; break;
45173			}
45174
45175			h /= 6;
45176		}
45177
45178		return { h: h, s: s, l: l };
45179	}
45180
45181// `hslToRgb`
45182// Converts an HSL color value to RGB.
45183// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
45184// *Returns:* { r, g, b } in the set [0, 255]
45185	function hslToRgb(h, s, l) {
45186		var r, g, b;
45187
45188		h = bound01(h, 360);
45189		s = bound01(s, 100);
45190		l = bound01(l, 100);
45191
45192		function hue2rgb(p, q, t) {
45193			if(t < 0) t += 1;
45194			if(t > 1) t -= 1;
45195			if(t < 1/6) return p + (q - p) * 6 * t;
45196			if(t < 1/2) return q;
45197			if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
45198			return p;
45199		}
45200
45201		if(s === 0) {
45202			r = g = b = l; // achromatic
45203		}
45204		else {
45205			var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
45206			var p = 2 * l - q;
45207			r = hue2rgb(p, q, h + 1/3);
45208			g = hue2rgb(p, q, h);
45209			b = hue2rgb(p, q, h - 1/3);
45210		}
45211
45212		return { r: r * 255, g: g * 255, b: b * 255 };
45213	}
45214
45215// `rgbToHsv`
45216// Converts an RGB color value to HSV
45217// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
45218// *Returns:* { h, s, v } in [0,1]
45219	function rgbToHsv(r, g, b) {
45220
45221		r = bound01(r, 255);
45222		g = bound01(g, 255);
45223		b = bound01(b, 255);
45224
45225		var max = mathMax(r, g, b), min = mathMin(r, g, b);
45226		var h, s, v = max;
45227
45228		var d = max - min;
45229		s = max === 0 ? 0 : d / max;
45230
45231		if(max == min) {
45232			h = 0; // achromatic
45233		}
45234		else {
45235			switch(max) {
45236				case r: h = (g - b) / d + (g < b ? 6 : 0); break;
45237				case g: h = (b - r) / d + 2; break;
45238				case b: h = (r - g) / d + 4; break;
45239			}
45240			h /= 6;
45241		}
45242		return { h: h, s: s, v: v };
45243	}
45244
45245// `hsvToRgb`
45246// Converts an HSV color value to RGB.
45247// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
45248// *Returns:* { r, g, b } in the set [0, 255]
45249	function hsvToRgb(h, s, v) {
45250
45251		h = bound01(h, 360) * 6;
45252		s = bound01(s, 100);
45253		v = bound01(v, 100);
45254
45255		var i = Math.floor(h),
45256			f = h - i,
45257			p = v * (1 - s),
45258			q = v * (1 - f * s),
45259			t = v * (1 - (1 - f) * s),
45260			mod = i % 6,
45261			r = [v, q, p, p, t, v][mod],
45262			g = [t, v, v, q, p, p][mod],
45263			b = [p, p, t, v, v, q][mod];
45264
45265		return { r: r * 255, g: g * 255, b: b * 255 };
45266	}
45267
45268// `rgbToHex`
45269// Converts an RGB color to hex
45270// Assumes r, g, and b are contained in the set [0, 255]
45271// Returns a 3 or 6 character hex
45272	function rgbToHex(r, g, b, allow3Char) {
45273
45274		var hex = [
45275			pad2(mathRound(r).toString(16)),
45276			pad2(mathRound(g).toString(16)),
45277			pad2(mathRound(b).toString(16))
45278		];
45279
45280		// Return a 3 character hex if possible
45281		if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
45282			return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
45283		}
45284
45285		return hex.join("");
45286	}
45287
45288// `rgbaToHex`
45289// Converts an RGBA color plus alpha transparency to hex
45290// Assumes r, g, b are contained in the set [0, 255] and
45291// a in [0, 1]. Returns a 4 or 8 character rgba hex
45292	function rgbaToHex(r, g, b, a, allow4Char) {
45293
45294		var hex = [
45295			pad2(mathRound(r).toString(16)),
45296			pad2(mathRound(g).toString(16)),
45297			pad2(mathRound(b).toString(16)),
45298			pad2(convertDecimalToHex(a))
45299		];
45300
45301		// Return a 4 character hex if possible
45302		if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {
45303			return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
45304		}
45305
45306		return hex.join("");
45307	}
45308
45309// `rgbaToArgbHex`
45310// Converts an RGBA color to an ARGB Hex8 string
45311// Rarely used, but required for "toFilter()"
45312	function rgbaToArgbHex(r, g, b, a) {
45313
45314		var hex = [
45315			pad2(convertDecimalToHex(a)),
45316			pad2(mathRound(r).toString(16)),
45317			pad2(mathRound(g).toString(16)),
45318			pad2(mathRound(b).toString(16))
45319		];
45320
45321		return hex.join("");
45322	}
45323
45324// `equals`
45325// Can be called with any tinycolor input
45326	tinycolor.equals = function (color1, color2) {
45327		if (!color1 || !color2) { return false; }
45328		return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
45329	};
45330
45331	tinycolor.random = function() {
45332		return tinycolor.fromRatio({
45333			r: mathRandom(),
45334			g: mathRandom(),
45335			b: mathRandom()
45336		});
45337	};
45338
45339
45340// Modification Functions
45341// ----------------------
45342// Thanks to less.js for some of the basics here
45343// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
45344
45345	function desaturate(color, amount) {
45346		amount = (amount === 0) ? 0 : (amount || 10);
45347		var hsl = tinycolor(color).toHsl();
45348		hsl.s -= amount / 100;
45349		hsl.s = clamp01(hsl.s);
45350		return tinycolor(hsl);
45351	}
45352
45353	function saturate(color, amount) {
45354		amount = (amount === 0) ? 0 : (amount || 10);
45355		var hsl = tinycolor(color).toHsl();
45356		hsl.s += amount / 100;
45357		hsl.s = clamp01(hsl.s);
45358		return tinycolor(hsl);
45359	}
45360
45361	function greyscale(color) {
45362		return tinycolor(color).desaturate(100);
45363	}
45364
45365	function lighten (color, amount) {
45366		amount = (amount === 0) ? 0 : (amount || 10);
45367		var hsl = tinycolor(color).toHsl();
45368		hsl.l += amount / 100;
45369		hsl.l = clamp01(hsl.l);
45370		return tinycolor(hsl);
45371	}
45372
45373	function brighten(color, amount) {
45374		amount = (amount === 0) ? 0 : (amount || 10);
45375		var rgb = tinycolor(color).toRgb();
45376		rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
45377		rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
45378		rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
45379		return tinycolor(rgb);
45380	}
45381
45382	function darken (color, amount) {
45383		amount = (amount === 0) ? 0 : (amount || 10);
45384		var hsl = tinycolor(color).toHsl();
45385		hsl.l -= amount / 100;
45386		hsl.l = clamp01(hsl.l);
45387		return tinycolor(hsl);
45388	}
45389
45390// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
45391// Values outside of this range will be wrapped into this range.
45392	function spin(color, amount) {
45393		var hsl = tinycolor(color).toHsl();
45394		var hue = (hsl.h + amount) % 360;
45395		hsl.h = hue < 0 ? 360 + hue : hue;
45396		return tinycolor(hsl);
45397	}
45398
45399// Combination Functions
45400// ---------------------
45401// Thanks to jQuery xColor for some of the ideas behind these
45402// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
45403
45404	function complement(color) {
45405		var hsl = tinycolor(color).toHsl();
45406		hsl.h = (hsl.h + 180) % 360;
45407		return tinycolor(hsl);
45408	}
45409
45410	function triad(color) {
45411		var hsl = tinycolor(color).toHsl();
vendor: 1,173 bytes, lines 45412-45458
45412		var h = hsl.h;
45413		return [
45414			tinycolor(color),
45415			tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
45416			tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
45417		];
45418	}
45419
45420	function tetrad(color) {
45421		var hsl = tinycolor(color).toHsl();
45422		var h = hsl.h;
45423		return [
45424			tinycolor(color),
45425			tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
45426			tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
45427			tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
45428		];
45429	}
45430
45431	function splitcomplement(color) {
45432		var hsl = tinycolor(color).toHsl();
45433		var h = hsl.h;
45434		return [
45435			tinycolor(color),
45436			tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
45437			tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
45438		];
45439	}
45440
45441	function analogous(color, results, slices) {
45442		results = results || 6;
45443		slices = slices || 30;
45444
45445		var hsl = tinycolor(color).toHsl();
45446		var part = 360 / slices;
45447		var ret = [tinycolor(color)];
45448
45449		for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
45450			hsl.h = (hsl.h + part) % 360;
45451			ret.push(tinycolor(hsl));
45452		}
45453		return ret;
45454	}
45455
45456	function monochromatic(color, results) {
45457		results = results || 6;
45458		var hsv = tinycolor(color).toHsv();
vendor: 4,276 bytes, lines 45459-45597
45459		var h = hsv.h, s = hsv.s, v = hsv.v;
45460		var ret = [];
45461		var modification = 1 / results;
45462
45463		while (results--) {
45464			ret.push(tinycolor({ h: h, s: s, v: v}));
45465			v = (v + modification) % 1;
45466		}
45467
45468		return ret;
45469	}
45470
45471// Utility Functions
45472// ---------------------
45473
45474	tinycolor.mix = function(color1, color2, amount) {
45475		amount = (amount === 0) ? 0 : (amount || 50);
45476
45477		var rgb1 = tinycolor(color1).toRgb();
45478		var rgb2 = tinycolor(color2).toRgb();
45479
45480		var p = amount / 100;
45481
45482		var rgba = {
45483			r: ((rgb2.r - rgb1.r) * p) + rgb1.r,
45484			g: ((rgb2.g - rgb1.g) * p) + rgb1.g,
45485			b: ((rgb2.b - rgb1.b) * p) + rgb1.b,
45486			a: ((rgb2.a - rgb1.a) * p) + rgb1.a
45487		};
45488
45489		return tinycolor(rgba);
45490	};
45491
45492
45493// Readability Functions
45494// ---------------------
45495// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
45496
45497// `contrast`
45498// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)
45499	tinycolor.readability = function(color1, color2) {
45500		var c1 = tinycolor(color1);
45501		var c2 = tinycolor(color2);
45502		return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05);
45503	};
45504
45505// `isReadable`
45506// Ensure that foreground and background color combinations meet WCAG2 guidelines.
45507// The third argument is an optional Object.
45508//      the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA';
45509//      the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'.
45510// If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}.
45511
45512// *Example*
45513//    tinycolor.isReadable("#000", "#111") => false
45514//    tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false
45515	tinycolor.isReadable = function(color1, color2, wcag2) {
45516		var readability = tinycolor.readability(color1, color2);
45517		var wcag2Parms, out;
45518
45519		out = false;
45520
45521		wcag2Parms = validateWCAG2Parms(wcag2);
45522		switch (wcag2Parms.level + wcag2Parms.size) {
45523			case "AAsmall":
45524			case "AAAlarge":
45525				out = readability >= 4.5;
45526				break;
45527			case "AAlarge":
45528				out = readability >= 3;
45529				break;
45530			case "AAAsmall":
45531				out = readability >= 7;
45532				break;
45533		}
45534		return out;
45535
45536	};
45537
45538// `mostReadable`
45539// Given a base color and a list of possible foreground or background
45540// colors for that base, returns the most readable color.
45541// Optionally returns Black or White if the most readable color is unreadable.
45542// *Example*
45543//    tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255"
45544//    tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString();  // "#ffffff"
45545//    tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3"
45546//    tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff"
45547	tinycolor.mostReadable = function(baseColor, colorList, args) {
45548		var bestColor = null;
45549		var bestScore = 0;
45550		var readability;
45551		var includeFallbackColors, level, size ;
45552		args = args || {};
45553		includeFallbackColors = args.includeFallbackColors ;
45554		level = args.level;
45555		size = args.size;
45556
45557		for (var i= 0; i < colorList.length ; i++) {
45558			readability = tinycolor.readability(baseColor, colorList[i]);
45559			if (readability > bestScore) {
45560				bestScore = readability;
45561				bestColor = tinycolor(colorList[i]);
45562			}
45563		}
45564
45565		if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) {
45566			return bestColor;
45567		}
45568		else {
45569			args.includeFallbackColors=false;
45570			return tinycolor.mostReadable(baseColor,["#fff", "#000"],args);
45571		}
45572	};
45573
45574
45575// Big List of Colors
45576// ------------------
45577// <http://www.w3.org/TR/css3-color/#svg-color>
45578	var names = tinycolor.names = {
45579		aliceblue: "f0f8ff",
45580		antiquewhite: "faebd7",
45581		aqua: "0ff",
45582		aquamarine: "7fffd4",
45583		azure: "f0ffff",
45584		beige: "f5f5dc",
45585		bisque: "ffe4c4",
45586		black: "000",
45587		blanchedalmond: "ffebcd",
45588		blue: "00f",
45589		blueviolet: "8a2be2",
45590		brown: "a52a2a",
45591		burlywood: "deb887",
45592		burntsienna: "ea7e5d",
45593		cadetblue: "5f9ea0",
45594		chartreuse: "7fff00",
45595		chocolate: "d2691e",
45596		coral: "ff7f50",
45597		cornflowerblue: "6495ed",
vendor: 4,115 bytes, lines 45598-45784
45598		cornsilk: "fff8dc",
45599		crimson: "dc143c",
45600		cyan: "0ff",
45601		darkblue: "00008b",
45602		darkcyan: "008b8b",
45603		darkgoldenrod: "b8860b",
45604		darkgray: "a9a9a9",
45605		darkgreen: "006400",
45606		darkgrey: "a9a9a9",
45607		darkkhaki: "bdb76b",
45608		darkmagenta: "8b008b",
45609		darkolivegreen: "556b2f",
45610		darkorange: "ff8c00",
45611		darkorchid: "9932cc",
45612		darkred: "8b0000",
45613		darksalmon: "e9967a",
45614		darkseagreen: "8fbc8f",
45615		darkslateblue: "483d8b",
45616		darkslategray: "2f4f4f",
45617		darkslategrey: "2f4f4f",
45618		darkturquoise: "00ced1",
45619		darkviolet: "9400d3",
45620		deeppink: "ff1493",
45621		deepskyblue: "00bfff",
45622		dimgray: "696969",
45623		dimgrey: "696969",
45624		dodgerblue: "1e90ff",
45625		firebrick: "b22222",
45626		floralwhite: "fffaf0",
45627		forestgreen: "228b22",
45628		fuchsia: "f0f",
45629		gainsboro: "dcdcdc",
45630		ghostwhite: "f8f8ff",
45631		gold: "ffd700",
45632		goldenrod: "daa520",
45633		gray: "808080",
45634		green: "008000",
45635		greenyellow: "adff2f",
45636		grey: "808080",
45637		honeydew: "f0fff0",
45638		hotpink: "ff69b4",
45639		indianred: "cd5c5c",
45640		indigo: "4b0082",
45641		ivory: "fffff0",
45642		khaki: "f0e68c",
45643		lavender: "e6e6fa",
45644		lavenderblush: "fff0f5",
45645		lawngreen: "7cfc00",
45646		lemonchiffon: "fffacd",
45647		lightblue: "add8e6",
45648		lightcoral: "f08080",
45649		lightcyan: "e0ffff",
45650		lightgoldenrodyellow: "fafad2",
45651		lightgray: "d3d3d3",
45652		lightgreen: "90ee90",
45653		lightgrey: "d3d3d3",
45654		lightpink: "ffb6c1",
45655		lightsalmon: "ffa07a",
45656		lightseagreen: "20b2aa",
45657		lightskyblue: "87cefa",
45658		lightslategray: "789",
45659		lightslategrey: "789",
45660		lightsteelblue: "b0c4de",
45661		lightyellow: "ffffe0",
45662		lime: "0f0",
45663		limegreen: "32cd32",
45664		linen: "faf0e6",
45665		magenta: "f0f",
45666		maroon: "800000",
45667		mediumaquamarine: "66cdaa",
45668		mediumblue: "0000cd",
45669		mediumorchid: "ba55d3",
45670		mediumpurple: "9370db",
45671		mediumseagreen: "3cb371",
45672		mediumslateblue: "7b68ee",
45673		mediumspringgreen: "00fa9a",
45674		mediumturquoise: "48d1cc",
45675		mediumvioletred: "c71585",
45676		midnightblue: "191970",
45677		mintcream: "f5fffa",
45678		mistyrose: "ffe4e1",
45679		moccasin: "ffe4b5",
45680		navajowhite: "ffdead",
45681		navy: "000080",
45682		oldlace: "fdf5e6",
45683		olive: "808000",
45684		olivedrab: "6b8e23",
45685		orange: "ffa500",
45686		orangered: "ff4500",
45687		orchid: "da70d6",
45688		palegoldenrod: "eee8aa",
45689		palegreen: "98fb98",
45690		paleturquoise: "afeeee",
45691		palevioletred: "db7093",
45692		papayawhip: "ffefd5",
45693		peachpuff: "ffdab9",
45694		peru: "cd853f",
45695		pink: "ffc0cb",
45696		plum: "dda0dd",
45697		powderblue: "b0e0e6",
45698		purple: "800080",
45699		rebeccapurple: "663399",
45700		red: "f00",
45701		rosybrown: "bc8f8f",
45702		royalblue: "4169e1",
45703		saddlebrown: "8b4513",
45704		salmon: "fa8072",
45705		sandybrown: "f4a460",
45706		seagreen: "2e8b57",
45707		seashell: "fff5ee",
45708		sienna: "a0522d",
45709		silver: "c0c0c0",
45710		skyblue: "87ceeb",
45711		slateblue: "6a5acd",
45712		slategray: "708090",
45713		slategrey: "708090",
45714		snow: "fffafa",
45715		springgreen: "00ff7f",
45716		steelblue: "4682b4",
45717		tan: "d2b48c",
45718		teal: "008080",
45719		thistle: "d8bfd8",
45720		tomato: "ff6347",
45721		turquoise: "40e0d0",
45722		violet: "ee82ee",
45723		wheat: "f5deb3",
45724		white: "fff",
45725		whitesmoke: "f5f5f5",
45726		yellow: "ff0",
45727		yellowgreen: "9acd32"
45728	};
45729
45730// Make it easy to access colors via `hexNames[hex]`
45731	var hexNames = tinycolor.hexNames = flip(names);
45732
45733
45734// Utilities
45735// ---------
45736
45737// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
45738	function flip(o) {
45739		var flipped = { };
45740		for (var i in o) {
45741			if (o.hasOwnProperty(i)) {
45742				flipped[o[i]] = i;
45743			}
45744		}
45745		return flipped;
45746	}
45747
45748// Return a valid alpha value [0,1] with all invalid values being set to 1
45749	function boundAlpha(a) {
45750		a = parseFloat(a);
45751
45752		if (isNaN(a) || a < 0 || a > 1) {
45753			a = 1;
45754		}
45755
45756		return a;
45757	}
45758
45759// Take input from [0, n] and return it as [0, 1]
45760	function bound01(n, max) {
45761		if (isOnePointZero(n)) { n = "100%"; }
45762
45763		var processPercent = isPercentage(n);
45764		n = mathMin(max, mathMax(0, parseFloat(n)));
45765
45766		// Automatically convert percentage into number
45767		if (processPercent) {
45768			n = parseInt(n * max, 10) / 100;
45769		}
45770
45771		// Handle floating point rounding errors
45772		if ((Math.abs(n - max) < 0.000001)) {
45773			return 1;
45774		}
45775
45776		// Convert into [0, 1] range if it isn't already
45777		return (n % max) / parseFloat(max);
45778	}
45779
45780// Force a number between 0 and 1
45781	function clamp01(val) {
45782		return mathMin(1, mathMax(0, val));
45783	}
45784
vendor: 6,073 bytes, lines 45785-45968
45785// Parse a base-16 hex value into a base-10 integer
45786	function parseIntFromHex(val) {
45787		return parseInt(val, 16);
45788	}
45789
45790// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
45791// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
45792	function isOnePointZero(n) {
45793		return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
45794	}
45795
45796// Check to see if string passed in is a percentage
45797	function isPercentage(n) {
45798		return typeof n === "string" && n.indexOf('%') != -1;
45799	}
45800
45801// Force a hex value to have 2 characters
45802	function pad2(c) {
45803		return c.length == 1 ? '0' + c : '' + c;
45804	}
45805
45806// Replace a decimal with it's percentage value
45807	function convertToPercentage(n) {
45808		if (n <= 1) {
45809			n = (n * 100) + "%";
45810		}
45811
45812		return n;
45813	}
45814
45815// Converts a decimal to a hex value
45816	function convertDecimalToHex(d) {
45817		return Math.round(parseFloat(d) * 255).toString(16);
45818	}
45819// Converts a hex value to a decimal
45820	function convertHexToDecimal(h) {
45821		return (parseIntFromHex(h) / 255);
45822	}
45823
45824	var matchers = (function() {
45825
45826		// <http://www.w3.org/TR/css3-values/#integers>
45827		var CSS_INTEGER = "[-\\+]?\\d+%?";
45828
45829		// <http://www.w3.org/TR/css3-values/#number-value>
45830		var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
45831
45832		// Allow positive/negative integer/number.  Don't capture the either/or, just the entire outcome.
45833		var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
45834
45835		// Actual matching.
45836		// Parentheses and commas are optional, but not required.
45837		// Whitespace can take the place of commas or opening paren
45838		var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
45839		var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
45840
45841		return {
45842			CSS_UNIT: new RegExp(CSS_UNIT),
45843			rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
45844			rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
45845			hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
45846			hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
45847			hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
45848			hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
45849			hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
45850			hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
45851			hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
45852			hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
45853		};
45854	})();
45855
45856// `isValidCSSUnit`
45857// Take in a single string / number and check to see if it looks like a CSS unit
45858// (see `matchers` above for definition).
45859	function isValidCSSUnit(color) {
45860		return !!matchers.CSS_UNIT.exec(color);
45861	}
45862
45863// `stringInputToObject`
45864// Permissive string parsing.  Take in a number of formats, and output an object
45865// based on detected format.  Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
45866	function stringInputToObject(color) {
45867
45868		color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
45869		var named = false;
45870		if (names[color]) {
45871			color = names[color];
45872			named = true;
45873		}
45874		else if (color == 'transparent') {
45875			return { r: 0, g: 0, b: 0, a: 0, format: "name" };
45876		}
45877
45878		// Try to match string input using regular expressions.
45879		// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
45880		// Just return an object and let the conversion functions handle that.
45881		// This way the result will be the same whether the tinycolor is initialized with string or object.
45882		var match;
45883		if ((match = matchers.rgb.exec(color))) {
45884			return { r: match[1], g: match[2], b: match[3] };
45885		}
45886		if ((match = matchers.rgba.exec(color))) {
45887			return { r: match[1], g: match[2], b: match[3], a: match[4] };
45888		}
45889		if ((match = matchers.hsl.exec(color))) {
45890			return { h: match[1], s: match[2], l: match[3] };
45891		}
45892		if ((match = matchers.hsla.exec(color))) {
45893			return { h: match[1], s: match[2], l: match[3], a: match[4] };
45894		}
45895		if ((match = matchers.hsv.exec(color))) {
45896			return { h: match[1], s: match[2], v: match[3] };
45897		}
45898		if ((match = matchers.hsva.exec(color))) {
45899			return { h: match[1], s: match[2], v: match[3], a: match[4] };
45900		}
45901		if ((match = matchers.hex8.exec(color))) {
45902			return {
45903				r: parseIntFromHex(match[1]),
45904				g: parseIntFromHex(match[2]),
45905				b: parseIntFromHex(match[3]),
45906				a: convertHexToDecimal(match[4]),
45907				format: named ? "name" : "hex8"
45908			};
45909		}
45910		if ((match = matchers.hex6.exec(color))) {
45911			return {
45912				r: parseIntFromHex(match[1]),
45913				g: parseIntFromHex(match[2]),
45914				b: parseIntFromHex(match[3]),
45915				format: named ? "name" : "hex"
45916			};
45917		}
45918		if ((match = matchers.hex4.exec(color))) {
45919			return {
45920				r: parseIntFromHex(match[1] + '' + match[1]),
45921				g: parseIntFromHex(match[2] + '' + match[2]),
45922				b: parseIntFromHex(match[3] + '' + match[3]),
45923				a: convertHexToDecimal(match[4] + '' + match[4]),
45924				format: named ? "name" : "hex8"
45925			};
45926		}
45927		if ((match = matchers.hex3.exec(color))) {
45928			return {
45929				r: parseIntFromHex(match[1] + '' + match[1]),
45930				g: parseIntFromHex(match[2] + '' + match[2]),
45931				b: parseIntFromHex(match[3] + '' + match[3]),
45932				format: named ? "name" : "hex"
45933			};
45934		}
45935
45936		return false;
45937	}
45938
45939	function validateWCAG2Parms(parms) {
45940		// return valid WCAG2 parms for isReadable.
45941		// If input parms are invalid, return {"level":"AA", "size":"small"}
45942		var level, size;
45943		parms = parms || {"level":"AA", "size":"small"};
45944		level = (parms.level || "AA").toUpperCase();
45945		size = (parms.size || "small").toLowerCase();
45946		if (level !== "AA" && level !== "AAA") {
45947			level = "AA";
45948		}
45949		if (size !== "small" && size !== "large") {
45950			size = "small";
45951		}
45952		return {"level":level, "size":size};
45953	}
45954
45955// Node: Export function
45956	if (typeof module !== "undefined" && module.exports) {
45957		module.exports = tinycolor;
45958	}
45959// AMD/requirejs: Define the module
45960	else if (typeof define === 'function' && define.amd) {
45961		define(function () {return tinycolor;});
45962	}
45963// Browser: Expose to window
45964	else {
45965		window.tinycolor = tinycolor;
45966	}
45967
45968})(Math);

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.