vendor: 5,117 bytes, lines 1-134
1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40/******/ } 41/******/ }; 42/******/ 43/******/ // define __esModule on exports 44/******/ __webpack_require__.r = function(exports) { 45/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47/******/ } 48/******/ Object.defineProperty(exports, '__esModule', { value: true }); 49/******/ }; 50/******/ 51/******/ // create a fake namespace object 52/******/ // mode & 1: value is a module id, require it 53/******/ // mode & 2: merge all properties of value into the ns 54/******/ // mode & 4: return value when already ns object 55/******/ // mode & 8|1: behave like require 56/******/ __webpack_require__.t = function(value, mode) { 57/******/ if(mode & 1) value = __webpack_require__(value); 58/******/ if(mode & 8) return value; 59/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60/******/ var ns = Object.create(null); 61/******/ __webpack_require__.r(ns); 62/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64/******/ return ns; 65/******/ }; 66/******/ 67/******/ // getDefaultExport function for compatibility with non-harmony modules 68/******/ __webpack_require__.n = function(module) { 69/******/ var getter = module && module.__esModule ? 70/******/ function getDefault() { return module['default']; } : 71/******/ function getModuleExports() { return module; }; 72/******/ __webpack_require__.d(getter, 'a', getter); 73/******/ return getter; 74/******/ }; 75/******/ 76/******/ // Object.prototype.hasOwnProperty.call 77/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78/******/ 79/******/ // __webpack_public_path__ 80/******/ __webpack_require__.p = ""; 81/******/ 82/******/ 83/******/ // Load entry module and return exports 84/******/ return __webpack_require__(__webpack_require__.s = 7); 85/******/ }) 86/************************************************************************/ 87/******/ ([ 88/* 0 */ 89/***/ (function(module, exports, __webpack_require__) { 90 91var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 92 * jQuery JavaScript Library v3.6.0 93 * https://jquery.com/ 94 * 95 * Includes Sizzle.js 96 * https://sizzlejs.com/ 97 * 98 * Copyright OpenJS Foundation and other contributors 99 * Released under the MIT license 100 * https://jquery.org/license 101 * 102 * Date: 2021-03-02T17:08Z 103 */ 104( function( global, factory ) { 105 106 "use strict"; 107 108 if ( true && typeof module.exports === "object" ) { 109 110 // For CommonJS and CommonJS-like environments where a proper `window` 111 // is present, execute the factory and get jQuery. 112 // For environments that do not have a `window` with a `document` 113 // (such as Node.js), expose a factory as module.exports. 114 // This accentuates the need for the creation of a real `window`. 115 // e.g. var jQuery = require("jquery")(window); 116 // See ticket #14549 for more info. 117 module.exports = global.document ? 118 factory( global, true ) : 119 function( w ) { 120 if ( !w.document ) { 121 throw new Error( "jQuery requires a window with a document" ); 122 } 123 return factory( w ); 124 }; 125 } else { 126 factory( global ); 127 } 128 129// Pass this if window is not defined yet 130} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 131 132// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 133// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 134// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), str
vendor: 2,883 bytes, lines 134-244
134ict mode should be common 135// enough that all such attempts are guarded in a try block. 136"use strict"; 137 138var arr = []; 139 140var getProto = Object.getPrototypeOf; 141 142var slice = arr.slice; 143 144var flat = arr.flat ? function( array ) { 145 return arr.flat.call( array ); 146} : function( array ) { 147 return arr.concat.apply( [], array ); 148}; 149 150 151var push = arr.push; 152 153var indexOf = arr.indexOf; 154 155var class2type = {}; 156 157var toString = class2type.toString; 158 159var hasOwn = class2type.hasOwnProperty; 160 161var fnToString = hasOwn.toString; 162 163var ObjectFunctionString = fnToString.call( Object ); 164 165var support = {}; 166 167var isFunction = function isFunction( obj ) { 168 169 // Support: Chrome <=57, Firefox <=52 170 // In some browsers, typeof returns "function" for HTML <object> elements 171 // (i.e., `typeof document.createElement( "object" ) === "function"`). 172 // We don't want to classify *any* DOM node as a function. 173 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 174 // Plus for old WebKit, typeof returns "function" for HTML collections 175 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 176 return typeof obj === "function" && typeof obj.nodeType !== "number" && 177 typeof obj.item !== "function"; 178 }; 179 180 181var isWindow = function isWindow( obj ) { 182 return obj != null && obj === obj.window; 183 }; 184 185 186var document = window.document; 187 188 189 190 var preservedScriptAttributes = { 191 type: true, 192 src: true, 193 nonce: true, 194 noModule: true 195 }; 196 197 function DOMEval( code, node, doc ) { 198 doc = doc || document; 199 200 var i, val, 201 script = doc.createElement( "script" ); 202 203 script.text = code; 204 if ( node ) { 205 for ( i in preservedScriptAttributes ) { 206 207 // Support: Firefox 64+, Edge 18+ 208 // Some browsers don't support the "nonce" property on scripts. 209 // On the other hand, just using `getAttribute` is not enough as 210 // the `nonce` attribute is reset to an empty string whenever it 211 // becomes browsing-context connected. 212 // See https://github.com/whatwg/html/issues/2369 213 // See https://html.spec.whatwg.org/#nonce-attributes 214 // The `node.getAttribute` check was added for the sake of 215 // `jQuery.globalEval` so that it can fake a nonce-containing node 216 // via an object. 217 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 218 if ( val ) { 219 script.setAttribute( i, val ); 220 } 221 } 222 } 223 doc.head.appendChild( script ).parentNode.removeChild( script ); 224 } 225 226 227function toType( obj ) { 228 if ( obj == null ) { 229 return obj + ""; 230 } 231 232 // Support: Android <=2.3 only (functionish RegExp) 233 return typeof obj === "object" || typeof obj === "function" ? 234 class2type[ toString.call( obj ) ] || "object" : 235 typeof obj; 236} 237/* global Symbol */ 238// Defining this global in .eslintrc.json would create a danger of using the global 239// unguarded in another place, it seems safer to define global only for this module 240 241 242 243var 244 version = "3.6.0
vendor: 183,283 bytes, lines 244-7039
244", 245 246 // Define a local copy of jQuery 247 jQuery = function( selector, context ) { 248 249 // The jQuery object is actually just the init constructor 'enhanced' 250 // Need init if jQuery is called (just allow error to be thrown if not included) 251 return new jQuery.fn.init( selector, context ); 252 }; 253 254jQuery.fn = jQuery.prototype = { 255 256 // The current version of jQuery being used 257 jquery: version, 258 259 constructor: jQuery, 260 261 // The default length of a jQuery object is 0 262 length: 0, 263 264 toArray: function() { 265 return slice.call( this ); 266 }, 267 268 // Get the Nth element in the matched element set OR 269 // Get the whole matched element set as a clean array 270 get: function( num ) { 271 272 // Return all the elements in a clean array 273 if ( num == null ) { 274 return slice.call( this ); 275 } 276 277 // Return just the one element from the set 278 return num < 0 ? this[ num + this.length ] : this[ num ]; 279 }, 280 281 // Take an array of elements and push it onto the stack 282 // (returning the new matched element set) 283 pushStack: function( elems ) { 284 285 // Build a new jQuery matched element set 286 var ret = jQuery.merge( this.constructor(), elems ); 287 288 // Add the old object onto the stack (as a reference) 289 ret.prevObject = this; 290 291 // Return the newly-formed element set 292 return ret; 293 }, 294 295 // Execute a callback for every element in the matched set. 296 each: function( callback ) { 297 return jQuery.each( this, callback ); 298 }, 299 300 map: function( callback ) { 301 return this.pushStack( jQuery.map( this, function( elem, i ) { 302 return callback.call( elem, i, elem ); 303 } ) ); 304 }, 305 306 slice: function() { 307 return this.pushStack( slice.apply( this, arguments ) ); 308 }, 309 310 first: function() { 311 return this.eq( 0 ); 312 }, 313 314 last: function() { 315 return this.eq( -1 ); 316 }, 317 318 even: function() { 319 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 320 return ( i + 1 ) % 2; 321 } ) ); 322 }, 323 324 odd: function() { 325 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 326 return i % 2; 327 } ) ); 328 }, 329 330 eq: function( i ) { 331 var len = this.length, 332 j = +i + ( i < 0 ? len : 0 ); 333 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 334 }, 335 336 end: function() { 337 return this.prevObject || this.constructor(); 338 }, 339 340 // For internal use only. 341 // Behaves like an Array's method, not like a jQuery method. 342 push: push, 343 sort: arr.sort, 344 splice: arr.splice 345}; 346 347jQuery.extend = jQuery.fn.extend = function() { 348 var options, name, src, copy, copyIsArray, clone, 349 target = arguments[ 0 ] || {}, 350 i = 1, 351 length = arguments.length, 352 deep = false; 353 354 // Handle a deep copy situation 355 if ( typeof target === "boolean" ) { 356 deep = target; 357 358 // Skip the boolean and the target 359 target = arguments[ i ] || {}; 360 i++; 361 } 362 363 // Handle case when target is a string or something (possible in deep copy) 364 if ( typeof target !== "object" && !isFunction( target ) ) { 365 target = {}; 366 } 367 368 // Extend jQuery itself if only one argument is passed 369 if ( i === length ) { 370 target = this; 371 i--; 372 } 373 374 for ( ; i < length; i++ ) { 375 376 // Only deal with non-null/undefined values 377 if ( ( options = arguments[ i ] ) != null ) { 378 379 // Extend the base object 380 for ( name in options ) { 381 copy = options[ name ]; 382 383 // Prevent Object.prototype pollution 384 // Prevent never-ending loop 385 if ( name === "__proto__" || target === copy ) { 386 continue; 387 } 388 389 // Recurse if we're merging plain objects or arrays 390 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 391 ( copyIsArray = Array.isArray( copy ) ) ) ) { 392 src = target[ name ]; 393 394 // Ensure proper type for the source value 395 if ( copyIsArray && !Array.isArray( src ) ) { 396 clone = []; 397 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 398 clone = {}; 399 } else { 400 clone = src; 401 } 402 copyIsArray = false; 403 404 // Never move original objects, clone them 405 target[ name ] = jQuery.extend( deep, clone, copy ); 406 407 // Don't bring in undefined values 408 } else if ( copy !== undefined ) { 409 target[ name ] = copy; 410 } 411 } 412 } 413 } 414 415 // Return the modified object 416 return target; 417}; 418 419jQuery.extend( { 420 421 // Unique for each copy of jQuery on the page 422 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 423 424 // Assume jQuery is ready without the ready module 425 isReady: true, 426 427 error: function( msg ) { 428 throw new Error( msg ); 429 }, 430 431 noop: function() {}, 432 433 isPlainObject: function( obj ) { 434 var proto, Ctor; 435 436 // Detect obvious negatives 437 // Use toString instead of jQuery.type to catch host objects 438 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 439 return false; 440 } 441 442 proto = getProto( obj ); 443 444 // Objects with no prototype (e.g., `Object.create( null )`) are plain 445 if ( !proto ) { 446 return true; 447 } 448 449 // Objects with prototype are plain iff they were constructed by a global Object function 450 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 451 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 452 }, 453 454 isEmptyObject: function( obj ) { 455 var name; 456 457 for ( name in obj ) { 458 return false; 459 } 460 return true; 461 }, 462 463 // Evaluates a script in a provided context; falls back to the global one 464 // if not specified. 465 globalEval: function( code, options, doc ) { 466 DOMEval( code, { nonce: options && options.nonce }, doc ); 467 }, 468 469 each: function( obj, callback ) { 470 var length, i = 0; 471 472 if ( isArrayLike( obj ) ) { 473 length = obj.length; 474 for ( ; i < length; i++ ) { 475 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 476 break; 477 } 478 } 479 } else { 480 for ( i in obj ) { 481 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 482 break; 483 } 484 } 485 } 486 487 return obj; 488 }, 489 490 // results is for internal usage only 491 makeArray: function( arr, results ) { 492 var ret = results || []; 493 494 if ( arr != null ) { 495 if ( isArrayLike( Object( arr ) ) ) { 496 jQuery.merge( ret, 497 typeof arr === "string" ? 498 [ arr ] : arr 499 ); 500 } else { 501 push.call( ret, arr ); 502 } 503 } 504 505 return ret; 506 }, 507 508 inArray: function( elem, arr, i ) { 509 return arr == null ? -1 : indexOf.call( arr, elem, i ); 510 }, 511 512 // Support: Android <=4.0 only, PhantomJS 1 only 513 // push.apply(_, arraylike) throws on ancient WebKit 514 merge: function( first, second ) { 515 var len = +second.length, 516 j = 0, 517 i = first.length; 518 519 for ( ; j < len; j++ ) { 520 first[ i++ ] = second[ j ]; 521 } 522 523 first.length = i; 524 525 return first; 526 }, 527 528 grep: function( elems, callback, invert ) { 529 var callbackInverse, 530 matches = [], 531 i = 0, 532 length = elems.length, 533 callbackExpect = !invert; 534 535 // Go through the array, only saving the items 536 // that pass the validator function 537 for ( ; i < length; i++ ) { 538 callbackInverse = !callback( elems[ i ], i ); 539 if ( callbackInverse !== callbackExpect ) { 540 matches.push( elems[ i ] ); 541 } 542 } 543 544 return matches; 545 }, 546 547 // arg is for internal usage only 548 map: function( elems, callback, arg ) { 549 var length, value, 550 i = 0, 551 ret = []; 552 553 // Go through the array, translating each of the items to their new values 554 if ( isArrayLike( elems ) ) { 555 length = elems.length; 556 for ( ; i < length; i++ ) { 557 value = callback( elems[ i ], i, arg ); 558 559 if ( value != null ) { 560 ret.push( value ); 561 } 562 } 563 564 // Go through every key on the object, 565 } else { 566 for ( i in elems ) { 567 value = callback( elems[ i ], i, arg ); 568 569 if ( value != null ) { 570 ret.push( value ); 571 } 572 } 573 } 574 575 // Flatten any nested arrays 576 return flat( ret ); 577 }, 578 579 // A global GUID counter for objects 580 guid: 1, 581 582 // jQuery.support is not used in Core but other projects attach their 583 // properties to it so it needs to exist. 584 support: support 585} ); 586 587if ( typeof Symbol === "function" ) { 588 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 589} 590 591// Populate the class2type map 592jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 593 function( _i, name ) { 594 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 595 } ); 596 597function isArrayLike( obj ) { 598 599 // Support: real iOS 8.2 only (not reproducible in simulator) 600 // `in` check used to prevent JIT error (gh-2145) 601 // hasOwn isn't used here due to false negatives 602 // regarding Nodelist length in IE 603 var length = !!obj && "length" in obj && obj.length, 604 type = toType( obj ); 605 606 if ( isFunction( obj ) || isWindow( obj ) ) { 607 return false; 608 } 609 610 return type === "array" || length === 0 || 611 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 612} 613var Sizzle = 614/*! 615 * Sizzle CSS Selector Engine v2.3.6 616 * https://sizzlejs.com/ 617 * 618 * Copyright JS Foundation and other contributors 619 * Released under the MIT license 620 * https://js.foundation/ 621 * 622 * Date: 2021-02-16 623 */ 624( function( window ) { 625var i, 626 support, 627 Expr, 628 getText, 629 isXML, 630 tokenize, 631 compile, 632 select, 633 outermostContext, 634 sortInput, 635 hasDuplicate, 636 637 // Local document vars 638 setDocument, 639 document, 640 docElem, 641 documentIsHTML, 642 rbuggyQSA, 643 rbuggyMatches, 644 matches, 645 contains, 646 647 // Instance-specific data 648 expando = "sizzle" + 1 * new Date(), 649 preferredDoc = window.document, 650 dirruns = 0, 651 done = 0, 652 classCache = createCache(), 653 tokenCache = createCache(), 654 compilerCache = createCache(), 655 nonnativeSelectorCache = createCache(), 656 sortOrder = function( a, b ) { 657 if ( a === b ) { 658 hasDuplicate = true; 659 } 660 return 0; 661 }, 662 663 // Instance methods 664 hasOwn = ( {} ).hasOwnProperty, 665 arr = [], 666 pop = arr.pop, 667 pushNative = arr.push, 668 push = arr.push, 669 slice = arr.slice, 670 671 // Use a stripped-down indexOf as it's faster than native 672 // https://jsperf.com/thor-indexof-vs-for/5 673 indexOf = function( list, elem ) { 674 var i = 0, 675 len = list.length; 676 for ( ; i < len; i++ ) { 677 if ( list[ i ] === elem ) { 678 return i; 679 } 680 } 681 return -1; 682 }, 683 684 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + 685 "ismap|loop|multiple|open|readonly|required|scoped", 686 687 // Regular expressions 688 689 // http://www.w3.org/TR/css3-selectors/#whitespace 690 whitespace = "[\\x20\\t\\r\\n\\f]", 691 692 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 693 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 694 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 695 696 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 697 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 698 699 // Operator (capture 2) 700 "*([*^$|!~]?=)" + whitespace + 701 702 // "Attribute values must be CSS identifiers [capture 5] 703 // or strings [capture 3 or capture 4]" 704 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 705 whitespace + "*\\]", 706 707 pseudos = ":(" + identifier + ")(?:\\((" + 708 709 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 710 // 1. quoted (capture 3; capture 4 or capture 5) 711 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 712 713 // 2. simple (capture 6) 714 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 715 716 // 3. anything else (capture 2) 717 ".*" + 718 ")\\)|)", 719 720 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 721 rwhitespace = new RegExp( whitespace + "+", "g" ), 722 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 723 whitespace + "+$", "g" ), 724 725 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 726 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + 727 "*" ), 728 rdescend = new RegExp( whitespace + "|>" ), 729 730 rpseudo = new RegExp( pseudos ), 731 ridentifier = new RegExp( "^" + identifier + "$" ), 732 733 matchExpr = { 734 "ID": new RegExp( "^#(" + identifier + ")" ), 735 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 736 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 737 "ATTR": new RegExp( "^" + attributes ), 738 "PSEUDO": new RegExp( "^" + pseudos ), 739 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 740 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 741 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 742 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 743 744 // For use in libraries implementing .is() 745 // We use this for POS matching in `select` 746 "needsContext": new RegExp( "^" + whitespace + 747 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 748 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 749 }, 750 751 rhtml = /HTML$/i, 752 rinputs = /^(?:input|select|textarea|button)$/i, 753 rheader = /^h\d$/i, 754 755 rnative = /^[^{]+\{\s*\[native \w/, 756 757 // Easily-parseable/retrievable ID or TAG or CLASS selectors 758 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 759 760 rsibling = /[+~]/, 761 762 // CSS escapes 763 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 764 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), 765 funescape = function( escape, nonHex ) { 766 var high = "0x" + escape.slice( 1 ) - 0x10000; 767 768 return nonHex ? 769 770 // Strip the backslash prefix from a non-hex escape sequence 771 nonHex : 772 773 // Replace a hexadecimal escape sequence with the encoded Unicode code point 774 // Support: IE <=11+ 775 // For values outside the Basic Multilingual Plane (BMP), manually construct a 776 // surrogate pair 777 high < 0 ? 778 String.fromCharCode( high + 0x10000 ) : 779 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 780 }, 781 782 // CSS string/identifier serialization 783 // https://drafts.csswg.org/cssom/#common-serializing-idioms 784 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 785 fcssescape = function( ch, asCodePoint ) { 786 if ( asCodePoint ) { 787 788 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 789 if ( ch === "\0" ) { 790 return "\uFFFD"; 791 } 792 793 // Control characters and (dependent upon position) numbers get escaped as code points 794 return ch.slice( 0, -1 ) + "\\" + 795 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 796 } 797 798 // Other potentially-special ASCII characters get backslash-escaped 799 return "\\" + ch; 800 }, 801 802 // Used for iframes 803 // See setDocument() 804 // Removing the function wrapper causes a "Permission Denied" 805 // error in IE 806 unloadHandler = function() { 807 setDocument(); 808 }, 809 810 inDisabledFieldset = addCombinator( 811 function( elem ) { 812 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 813 }, 814 { dir: "parentNode", next: "legend" } 815 ); 816 817// Optimize for push.apply( _, NodeList ) 818try { 819 push.apply( 820 ( arr = slice.call( preferredDoc.childNodes ) ), 821 preferredDoc.childNodes 822 ); 823 824 // Support: Android<4.0 825 // Detect silently failing push.apply 826 // eslint-disable-next-line no-unused-expressions 827 arr[ preferredDoc.childNodes.length ].nodeType; 828} catch ( e ) { 829 push = { apply: arr.length ? 830 831 // Leverage slice if possible 832 function( target, els ) { 833 pushNative.apply( target, slice.call( els ) ); 834 } : 835 836 // Support: IE<9 837 // Otherwise append directly 838 function( target, els ) { 839 var j = target.length, 840 i = 0; 841 842 // Can't trust NodeList.length 843 while ( ( target[ j++ ] = els[ i++ ] ) ) {} 844 target.length = j - 1; 845 } 846 }; 847} 848 849function Sizzle( selector, context, results, seed ) { 850 var m, i, elem, nid, match, groups, newSelector, 851 newContext = context && context.ownerDocument, 852 853 // nodeType defaults to 9, since context defaults to document 854 nodeType = context ? context.nodeType : 9; 855 856 results = results || []; 857 858 // Return early from calls with invalid selector or context 859 if ( typeof selector !== "string" || !selector || 860 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 861 862 return results; 863 } 864 865 // Try to shortcut find operations (as opposed to filters) in HTML documents 866 if ( !seed ) { 867 setDocument( context ); 868 context = context || document; 869 870 if ( documentIsHTML ) { 871 872 // If the selector is sufficiently simple, try using a "get*By*" DOM method 873 // (excepting DocumentFragment context, where the methods don't exist) 874 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 875 876 // ID selector 877 if ( ( m = match[ 1 ] ) ) { 878 879 // Document context 880 if ( nodeType === 9 ) { 881 if ( ( elem = context.getElementById( m ) ) ) { 882 883 // Support: IE, Opera, Webkit 884 // TODO: identify versions 885 // getElementById can match elements by name instead of ID 886 if ( elem.id === m ) { 887 results.push( elem ); 888 return results; 889 } 890 } else { 891 return results; 892 } 893 894 // Element context 895 } else { 896 897 // Support: IE, Opera, Webkit 898 // TODO: identify versions 899 // getElementById can match elements by name instead of ID 900 if ( newContext && ( elem = newContext.getElementById( m ) ) && 901 contains( context, elem ) && 902 elem.id === m ) { 903 904 results.push( elem ); 905 return results; 906 } 907 } 908 909 // Type selector 910 } else if ( match[ 2 ] ) { 911 push.apply( results, context.getElementsByTagName( selector ) ); 912 return results; 913 914 // Class selector 915 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && 916 context.getElementsByClassName ) { 917 918 push.apply( results, context.getElementsByClassName( m ) ); 919 return results; 920 } 921 } 922 923 // Take advantage of querySelectorAll 924 if ( support.qsa && 925 !nonnativeSelectorCache[ selector + " " ] && 926 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && 927 928 // Support: IE 8 only 929 // Exclude object elements 930 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { 931 932 newSelector = selector; 933 newContext = context; 934 935 // qSA considers elements outside a scoping root when evaluating child or 936 // descendant combinators, which is not what we want. 937 // In such cases, we work around the behavior by prefixing every selector in the 938 // list with an ID selector referencing the scope context. 939 // The technique has to be used as well when a leading combinator is used 940 // as such selectors are not recognized by querySelectorAll. 941 // Thanks to Andrew Dupont for this technique. 942 if ( nodeType === 1 && 943 ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { 944 945 // Expand context for sibling selectors 946 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 947 context; 948 949 // We can use :scope instead of the ID hack if the browser 950 // supports it & if we're not changing the context. 951 if ( newContext !== context || !support.scope ) { 952 953 // Capture the context ID, setting it first if necessary 954 if ( ( nid = context.getAttribute( "id" ) ) ) { 955 nid = nid.replace( rcssescape, fcssescape ); 956 } else { 957 context.setAttribute( "id", ( nid = expando ) ); 958 } 959 } 960 961 // Prefix every selector in the list 962 groups = tokenize( selector ); 963 i = groups.length; 964 while ( i-- ) { 965 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 966 toSelector( groups[ i ] ); 967 } 968 newSelector = groups.join( "," ); 969 } 970 971 try { 972 push.apply( results, 973 newContext.querySelectorAll( newSelector ) 974 ); 975 return results; 976 } catch ( qsaError ) { 977 nonnativeSelectorCache( selector, true ); 978 } finally { 979 if ( nid === expando ) { 980 context.removeAttribute( "id" ); 981 } 982 } 983 } 984 } 985 } 986 987 // All others 988 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 989} 990 991/** 992 * Create key-value caches of limited size 993 * @returns {function(string, object)} Returns the Object data after storing it on itself with 994 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 995 * deleting the oldest entry 996 */ 997function createCache() { 998 var keys = []; 999 1000 function cache( key, value ) { 1001 1002 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 1003 if ( keys.push( key + " " ) > Expr.cacheLength ) { 1004 1005 // Only keep the most recent entries 1006 delete cache[ keys.shift() ]; 1007 } 1008 return ( cache[ key + " " ] = value ); 1009 } 1010 return cache; 1011} 1012 1013/** 1014 * Mark a function for special use by Sizzle 1015 * @param {Function} fn The function to mark 1016 */ 1017function markFunction( fn ) { 1018 fn[ expando ] = true; 1019 return fn; 1020} 1021 1022/** 1023 * Support testing using an element 1024 * @param {Function} fn Passed the created element and returns a boolean result 1025 */ 1026function assert( fn ) { 1027 var el = document.createElement( "fieldset" ); 1028 1029 try { 1030 return !!fn( el ); 1031 } catch ( e ) { 1032 return false; 1033 } finally { 1034 1035 // Remove from its parent by default 1036 if ( el.parentNode ) { 1037 el.parentNode.removeChild( el ); 1038 } 1039 1040 // release memory in IE 1041 el = null; 1042 } 1043} 1044 1045/** 1046 * Adds the same handler for all of the specified attrs 1047 * @param {String} attrs Pipe-separated list of attributes 1048 * @param {Function} handler The method that will be applied 1049 */ 1050function addHandle( attrs, handler ) { 1051 var arr = attrs.split( "|" ), 1052 i = arr.length; 1053 1054 while ( i-- ) { 1055 Expr.attrHandle[ arr[ i ] ] = handler; 1056 } 1057} 1058 1059/** 1060 * Checks document order of two siblings 1061 * @param {Element} a 1062 * @param {Element} b 1063 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 1064 */ 1065function siblingCheck( a, b ) { 1066 var cur = b && a, 1067 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 1068 a.sourceIndex - b.sourceIndex; 1069 1070 // Use IE sourceIndex if available on both nodes 1071 if ( diff ) { 1072 return diff; 1073 } 1074 1075 // Check if b follows a 1076 if ( cur ) { 1077 while ( ( cur = cur.nextSibling ) ) { 1078 if ( cur === b ) { 1079 return -1; 1080 } 1081 } 1082 } 1083 1084 return a ? 1 : -1; 1085} 1086 1087/** 1088 * Returns a function to use in pseudos for input types 1089 * @param {String} type 1090 */ 1091function createInputPseudo( type ) { 1092 return function( elem ) { 1093 var name = elem.nodeName.toLowerCase(); 1094 return name === "input" && elem.type === type; 1095 }; 1096} 1097 1098/** 1099 * Returns a function to use in pseudos for buttons 1100 * @param {String} type 1101 */ 1102function createButtonPseudo( type ) { 1103 return function( elem ) { 1104 var name = elem.nodeName.toLowerCase(); 1105 return ( name === "input" || name === "button" ) && elem.type === type; 1106 }; 1107} 1108 1109/** 1110 * Returns a function to use in pseudos for :enabled/:disabled 1111 * @param {Boolean} disabled true for :disabled; false for :enabled 1112 */ 1113function createDisabledPseudo( disabled ) { 1114 1115 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 1116 return function( elem ) { 1117 1118 // Only certain elements can match :enabled or :disabled 1119 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 1120 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 1121 if ( "form" in elem ) { 1122 1123 // Check for inherited disabledness on relevant non-disabled elements: 1124 // * listed form-associated elements in a disabled fieldset 1125 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 1126 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 1127 // * option elements in a disabled optgroup 1128 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 1129 // All such elements have a "form" property. 1130 if ( elem.parentNode && elem.disabled === false ) { 1131 1132 // Option elements defer to a parent optgroup if present 1133 if ( "label" in elem ) { 1134 if ( "label" in elem.parentNode ) { 1135 return elem.parentNode.disabled === disabled; 1136 } else { 1137 return elem.disabled === disabled; 1138 } 1139 } 1140 1141 // Support: IE 6 - 11 1142 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 1143 return elem.isDisabled === disabled || 1144 1145 // Where there is no isDisabled, check manually 1146 /* jshint -W018 */ 1147 elem.isDisabled !== !disabled && 1148 inDisabledFieldset( elem ) === disabled; 1149 } 1150 1151 return elem.disabled === disabled; 1152 1153 // Try to winnow out elements that can't be disabled before trusting the disabled property. 1154 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 1155 // even exist on them, let alone have a boolean value. 1156 } else if ( "label" in elem ) { 1157 return elem.disabled === disabled; 1158 } 1159 1160 // Remaining elements are neither :enabled nor :disabled 1161 return false; 1162 }; 1163} 1164 1165/** 1166 * Returns a function to use in pseudos for positionals 1167 * @param {Function} fn 1168 */ 1169function createPositionalPseudo( fn ) { 1170 return markFunction( function( argument ) { 1171 argument = +argument; 1172 return markFunction( function( seed, matches ) { 1173 var j, 1174 matchIndexes = fn( [], seed.length, argument ), 1175 i = matchIndexes.length; 1176 1177 // Match elements found at the specified indexes 1178 while ( i-- ) { 1179 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 1180 seed[ j ] = !( matches[ j ] = seed[ j ] ); 1181 } 1182 } 1183 } ); 1184 } ); 1185} 1186 1187/** 1188 * Checks a node for validity as a Sizzle context 1189 * @param {Element|Object=} context 1190 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1191 */ 1192function testContext( context ) { 1193 return context && typeof context.getElementsByTagName !== "undefined" && context; 1194} 1195 1196// Expose support vars for convenience 1197support = Sizzle.support = {}; 1198 1199/** 1200 * Detects XML nodes 1201 * @param {Element|Object} elem An element or a document 1202 * @returns {Boolean} True iff elem is a non-HTML XML node 1203 */ 1204isXML = Sizzle.isXML = function( elem ) { 1205 var namespace = elem && elem.namespaceURI, 1206 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 1207 1208 // Support: IE <=8 1209 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 1210 // https://bugs.jquery.com/ticket/4833 1211 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 1212}; 1213 1214/** 1215 * Sets document-related variables once based on the current document 1216 * @param {Element|Object} [doc] An element or document object to use to set the document 1217 * @returns {Object} Returns the current document 1218 */ 1219setDocument = Sizzle.setDocument = function( node ) { 1220 var hasCompare, subWindow, 1221 doc = node ? node.ownerDocument || node : preferredDoc; 1222 1223 // Return early if doc is invalid or already selected 1224 // Support: IE 11+, Edge 17 - 18+ 1225 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1226 // two documents; shallow comparisons work. 1227 // eslint-disable-next-line eqeqeq 1228 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 1229 return document; 1230 } 1231 1232 // Update global variables 1233 document = doc; 1234 docElem = document.documentElement; 1235 documentIsHTML = !isXML( document ); 1236 1237 // Support: IE 9 - 11+, Edge 12 - 18+ 1238 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 1239 // Support: IE 11+, Edge 17 - 18+ 1240 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1241 // two documents; shallow comparisons work. 1242 // eslint-disable-next-line eqeqeq 1243 if ( preferredDoc != document && 1244 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 1245 1246 // Support: IE 11, Edge 1247 if ( subWindow.addEventListener ) { 1248 subWindow.addEventListener( "unload", unloadHandler, false ); 1249 1250 // Support: IE 9 - 10 only 1251 } else if ( subWindow.attachEvent ) { 1252 subWindow.attachEvent( "onunload", unloadHandler ); 1253 } 1254 } 1255 1256 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, 1257 // Safari 4 - 5 only, Opera <=11.6 - 12.x only 1258 // IE/Edge & older browsers don't support the :scope pseudo-class. 1259 // Support: Safari 6.0 only 1260 // Safari 6.0 supports :scope but it's an alias of :root there. 1261 support.scope = assert( function( el ) { 1262 docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); 1263 return typeof el.querySelectorAll !== "undefined" && 1264 !el.querySelectorAll( ":scope fieldset div" ).length; 1265 } ); 1266 1267 /* Attributes 1268 ---------------------------------------------------------------------- */ 1269 1270 // Support: IE<8 1271 // Verify that getAttribute really returns attributes and not properties 1272 // (excepting IE8 booleans) 1273 support.attributes = assert( function( el ) { 1274 el.className = "i"; 1275 return !el.getAttribute( "className" ); 1276 } ); 1277 1278 /* getElement(s)By* 1279 ---------------------------------------------------------------------- */ 1280 1281 // Check if getElementsByTagName("*") returns only elements 1282 support.getElementsByTagName = assert( function( el ) { 1283 el.appendChild( document.createComment( "" ) ); 1284 return !el.getElementsByTagName( "*" ).length; 1285 } ); 1286 1287 // Support: IE<9 1288 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 1289 1290 // Support: IE<10 1291 // Check if getElementById returns elements by name 1292 // The broken getElementById methods don't pick up programmatically-set names, 1293 // so use a roundabout getElementsByName test 1294 support.getById = assert( function( el ) { 1295 docElem.appendChild( el ).id = expando; 1296 return !document.getElementsByName || !document.getElementsByName( expando ).length; 1297 } ); 1298 1299 // ID filter and find 1300 if ( support.getById ) { 1301 Expr.filter[ "ID" ] = function( id ) { 1302 var attrId = id.replace( runescape, funescape ); 1303 return function( elem ) { 1304 return elem.getAttribute( "id" ) === attrId; 1305 }; 1306 }; 1307 Expr.find[ "ID" ] = function( id, context ) { 1308 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1309 var elem = context.getElementById( id ); 1310 return elem ? [ elem ] : []; 1311 } 1312 }; 1313 } else { 1314 Expr.filter[ "ID" ] = function( id ) { 1315 var attrId = id.replace( runescape, funescape ); 1316 return function( elem ) { 1317 var node = typeof elem.getAttributeNode !== "undefined" && 1318 elem.getAttributeNode( "id" ); 1319 return node && node.value === attrId; 1320 }; 1321 }; 1322 1323 // Support: IE 6 - 7 only 1324 // getElementById is not reliable as a find shortcut 1325 Expr.find[ "ID" ] = function( id, context ) { 1326 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1327 var node, i, elems, 1328 elem = context.getElementById( id ); 1329 1330 if ( elem ) { 1331 1332 // Verify the id attribute 1333 node = elem.getAttributeNode( "id" ); 1334 if ( node && node.value === id ) { 1335 return [ elem ]; 1336 } 1337 1338 // Fall back on getElementsByName 1339 elems = context.getElementsByName( id ); 1340 i = 0; 1341 while ( ( elem = elems[ i++ ] ) ) { 1342 node = elem.getAttributeNode( "id" ); 1343 if ( node && node.value === id ) { 1344 return [ elem ]; 1345 } 1346 } 1347 } 1348 1349 return []; 1350 } 1351 }; 1352 } 1353 1354 // Tag 1355 Expr.find[ "TAG" ] = support.getElementsByTagName ? 1356 function( tag, context ) { 1357 if ( typeof context.getElementsByTagName !== "undefined" ) { 1358 return context.getElementsByTagName( tag ); 1359 1360 // DocumentFragment nodes don't have gEBTN 1361 } else if ( support.qsa ) { 1362 return context.querySelectorAll( tag ); 1363 } 1364 } : 1365 1366 function( tag, context ) { 1367 var elem, 1368 tmp = [], 1369 i = 0, 1370 1371 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 1372 results = context.getElementsByTagName( tag ); 1373 1374 // Filter out possible comments 1375 if ( tag === "*" ) { 1376 while ( ( elem = results[ i++ ] ) ) { 1377 if ( elem.nodeType === 1 ) { 1378 tmp.push( elem ); 1379 } 1380 } 1381 1382 return tmp; 1383 } 1384 return results; 1385 }; 1386 1387 // Class 1388 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { 1389 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 1390 return context.getElementsByClassName( className ); 1391 } 1392 }; 1393 1394 /* QSA/matchesSelector 1395 ---------------------------------------------------------------------- */ 1396 1397 // QSA and matchesSelector support 1398 1399 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1400 rbuggyMatches = []; 1401 1402 // qSa(:focus) reports false when true (Chrome 21) 1403 // We allow this because of a bug in IE8/9 that throws an error 1404 // whenever `document.activeElement` is accessed on an iframe 1405 // So, we allow :focus to pass through QSA all the time to avoid the IE error 1406 // See https://bugs.jquery.com/ticket/13378 1407 rbuggyQSA = []; 1408 1409 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { 1410 1411 // Build QSA regex 1412 // Regex strategy adopted from Diego Perini 1413 assert( function( el ) { 1414 1415 var input; 1416 1417 // Select is set to empty string on purpose 1418 // This is to test IE's treatment of not explicitly 1419 // setting a boolean content attribute, 1420 // since its presence should be enough 1421 // https://bugs.jquery.com/ticket/12359 1422 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 1423 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 1424 "<option selected=''></option></select>"; 1425 1426 // Support: IE8, Opera 11-12.16 1427 // Nothing should be selected when empty strings follow ^= or $= or *= 1428 // The test attribute must be unknown in Opera but "safe" for WinRT 1429 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 1430 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { 1431 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 1432 } 1433 1434 // Support: IE8 1435 // Boolean attributes and "value" are not treated correctly 1436 if ( !el.querySelectorAll( "[selected]" ).length ) { 1437 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1438 } 1439 1440 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 1441 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1442 rbuggyQSA.push( "~=" ); 1443 } 1444 1445 // Support: IE 11+, Edge 15 - 18+ 1446 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 1447 // Adding a temporary attribute to the document before the selection works 1448 // around the issue. 1449 // Interestingly, IE 10 & older don't seem to have the issue. 1450 input = document.createElement( "input" ); 1451 input.setAttribute( "name", "" ); 1452 el.appendChild( input ); 1453 if ( !el.querySelectorAll( "[name='']" ).length ) { 1454 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 1455 whitespace + "*(?:''|\"\")" ); 1456 } 1457 1458 // Webkit/Opera - :checked should return selected option elements 1459 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1460 // IE8 throws error here and will not see later tests 1461 if ( !el.querySelectorAll( ":checked" ).length ) { 1462 rbuggyQSA.push( ":checked" ); 1463 } 1464 1465 // Support: Safari 8+, iOS 8+ 1466 // https://bugs.webkit.org/show_bug.cgi?id=136851 1467 // In-page `selector#id sibling-combinator selector` fails 1468 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 1469 rbuggyQSA.push( ".#.+[+~]" ); 1470 } 1471 1472 // Support: Firefox <=3.6 - 5 only 1473 // Old Firefox doesn't throw on a badly-escaped identifier. 1474 el.querySelectorAll( "\\\f" ); 1475 rbuggyQSA.push( "[\\r\\n\\f]" ); 1476 } ); 1477 1478 assert( function( el ) { 1479 el.innerHTML = "<a href='' disabled='disabled'></a>" + 1480 "<select disabled='disabled'><option/></select>"; 1481 1482 // Support: Windows 8 Native Apps 1483 // The type and name attributes are restricted during .innerHTML assignment 1484 var input = document.createElement( "input" ); 1485 input.setAttribute( "type", "hidden" ); 1486 el.appendChild( input ).setAttribute( "name", "D" ); 1487 1488 // Support: IE8 1489 // Enforce case-sensitivity of name attribute 1490 if ( el.querySelectorAll( "[name=d]" ).length ) { 1491 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 1492 } 1493 1494 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1495 // IE8 throws error here and will not see later tests 1496 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { 1497 rbuggyQSA.push( ":enabled", ":disabled" ); 1498 } 1499 1500 // Support: IE9-11+ 1501 // IE's :disabled selector does not pick up the children of disabled fieldsets 1502 docElem.appendChild( el ).disabled = true; 1503 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 1504 rbuggyQSA.push( ":enabled", ":disabled" ); 1505 } 1506 1507 // Support: Opera 10 - 11 only 1508 // Opera 10-11 does not throw on post-comma invalid pseudos 1509 el.querySelectorAll( "*,:x" ); 1510 rbuggyQSA.push( ",.*:" ); 1511 } ); 1512 } 1513 1514 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || 1515 docElem.webkitMatchesSelector || 1516 docElem.mozMatchesSelector || 1517 docElem.oMatchesSelector || 1518 docElem.msMatchesSelector ) ) ) ) { 1519 1520 assert( function( el ) { 1521 1522 // Check to see if it's possible to do matchesSelector 1523 // on a disconnected node (IE 9) 1524 support.disconnectedMatch = matches.call( el, "*" ); 1525 1526 // This should fail with an exception 1527 // Gecko does not error, returns false instead 1528 matches.call( el, "[s!='']:x" ); 1529 rbuggyMatches.push( "!=", pseudos ); 1530 } ); 1531 } 1532 1533 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 1534 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); 1535 1536 /* Contains 1537 ---------------------------------------------------------------------- */ 1538 hasCompare = rnative.test( docElem.compareDocumentPosition ); 1539 1540 // Element contains another 1541 // Purposefully self-exclusive 1542 // As in, an element does not contain itself 1543 contains = hasCompare || rnative.test( docElem.contains ) ? 1544 function( a, b ) { 1545 var adown = a.nodeType === 9 ? a.documentElement : a, 1546 bup = b && b.parentNode; 1547 return a === bup || !!( bup && bup.nodeType === 1 && ( 1548 adown.contains ? 1549 adown.contains( bup ) : 1550 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 1551 ) ); 1552 } : 1553 function( a, b ) { 1554 if ( b ) { 1555 while ( ( b = b.parentNode ) ) { 1556 if ( b === a ) { 1557 return true; 1558 } 1559 } 1560 } 1561 return false; 1562 }; 1563 1564 /* Sorting 1565 ---------------------------------------------------------------------- */ 1566 1567 // Document order sorting 1568 sortOrder = hasCompare ? 1569 function( a, b ) { 1570 1571 // Flag for duplicate removal 1572 if ( a === b ) { 1573 hasDuplicate = true; 1574 return 0; 1575 } 1576 1577 // Sort on method existence if only one input has compareDocumentPosition 1578 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1579 if ( compare ) { 1580 return compare; 1581 } 1582 1583 // Calculate position if both inputs belong to the same document 1584 // Support: IE 11+, Edge 17 - 18+ 1585 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1586 // two documents; shallow comparisons work. 1587 // eslint-disable-next-line eqeqeq 1588 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 1589 a.compareDocumentPosition( b ) : 1590 1591 // Otherwise we know they are disconnected 1592 1; 1593 1594 // Disconnected nodes 1595 if ( compare & 1 || 1596 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 1597 1598 // Choose the first element that is related to our preferred document 1599 // Support: IE 11+, Edge 17 - 18+ 1600 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1601 // two documents; shallow comparisons work. 1602 // eslint-disable-next-line eqeqeq 1603 if ( a == document || a.ownerDocument == preferredDoc && 1604 contains( preferredDoc, a ) ) { 1605 return -1; 1606 } 1607 1608 // Support: IE 11+, Edge 17 - 18+ 1609 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1610 // two documents; shallow comparisons work. 1611 // eslint-disable-next-line eqeqeq 1612 if ( b == document || b.ownerDocument == preferredDoc && 1613 contains( preferredDoc, b ) ) { 1614 return 1; 1615 } 1616 1617 // Maintain original order 1618 return sortInput ? 1619 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1620 0; 1621 } 1622 1623 return compare & 4 ? -1 : 1; 1624 } : 1625 function( a, b ) { 1626 1627 // Exit early if the nodes are identical 1628 if ( a === b ) { 1629 hasDuplicate = true; 1630 return 0; 1631 } 1632 1633 var cur, 1634 i = 0, 1635 aup = a.parentNode, 1636 bup = b.parentNode, 1637 ap = [ a ], 1638 bp = [ b ]; 1639 1640 // Parentless nodes are either documents or disconnected 1641 if ( !aup || !bup ) { 1642 1643 // Support: IE 11+, Edge 17 - 18+ 1644 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1645 // two documents; shallow comparisons work. 1646 /* eslint-disable eqeqeq */ 1647 return a == document ? -1 : 1648 b == document ? 1 : 1649 /* eslint-enable eqeqeq */ 1650 aup ? -1 : 1651 bup ? 1 : 1652 sortInput ? 1653 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1654 0; 1655 1656 // If the nodes are siblings, we can do a quick check 1657 } else if ( aup === bup ) { 1658 return siblingCheck( a, b ); 1659 } 1660 1661 // Otherwise we need full lists of their ancestors for comparison 1662 cur = a; 1663 while ( ( cur = cur.parentNode ) ) { 1664 ap.unshift( cur ); 1665 } 1666 cur = b; 1667 while ( ( cur = cur.parentNode ) ) { 1668 bp.unshift( cur ); 1669 } 1670 1671 // Walk down the tree looking for a discrepancy 1672 while ( ap[ i ] === bp[ i ] ) { 1673 i++; 1674 } 1675 1676 return i ? 1677 1678 // Do a sibling check if the nodes have a common ancestor 1679 siblingCheck( ap[ i ], bp[ i ] ) : 1680 1681 // Otherwise nodes in our document sort first 1682 // Support: IE 11+, Edge 17 - 18+ 1683 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1684 // two documents; shallow comparisons work. 1685 /* eslint-disable eqeqeq */ 1686 ap[ i ] == preferredDoc ? -1 : 1687 bp[ i ] == preferredDoc ? 1 : 1688 /* eslint-enable eqeqeq */ 1689 0; 1690 }; 1691 1692 return document; 1693}; 1694 1695Sizzle.matches = function( expr, elements ) { 1696 return Sizzle( expr, null, null, elements ); 1697}; 1698 1699Sizzle.matchesSelector = function( elem, expr ) { 1700 setDocument( elem ); 1701 1702 if ( support.matchesSelector && documentIsHTML && 1703 !nonnativeSelectorCache[ expr + " " ] && 1704 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 1705 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1706 1707 try { 1708 var ret = matches.call( elem, expr ); 1709 1710 // IE 9's matchesSelector returns false on disconnected nodes 1711 if ( ret || support.disconnectedMatch || 1712 1713 // As well, disconnected nodes are said to be in a document 1714 // fragment in IE 9 1715 elem.document && elem.document.nodeType !== 11 ) { 1716 return ret; 1717 } 1718 } catch ( e ) { 1719 nonnativeSelectorCache( expr, true ); 1720 } 1721 } 1722 1723 return Sizzle( expr, document, null, [ elem ] ).length > 0; 1724}; 1725 1726Sizzle.contains = function( context, elem ) { 1727 1728 // Set document vars if needed 1729 // Support: IE 11+, Edge 17 - 18+ 1730 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1731 // two documents; shallow comparisons work. 1732 // eslint-disable-next-line eqeqeq 1733 if ( ( context.ownerDocument || context ) != document ) { 1734 setDocument( context ); 1735 } 1736 return contains( context, elem ); 1737}; 1738 1739Sizzle.attr = function( elem, name ) { 1740 1741 // Set document vars if needed 1742 // Support: IE 11+, Edge 17 - 18+ 1743 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1744 // two documents; shallow comparisons work. 1745 // eslint-disable-next-line eqeqeq 1746 if ( ( elem.ownerDocument || elem ) != document ) { 1747 setDocument( elem ); 1748 } 1749 1750 var fn = Expr.attrHandle[ name.toLowerCase() ], 1751 1752 // Don't get fooled by Object.prototype properties (jQuery #13807) 1753 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1754 fn( elem, name, !documentIsHTML ) : 1755 undefined; 1756 1757 return val !== undefined ? 1758 val : 1759 support.attributes || !documentIsHTML ? 1760 elem.getAttribute( name ) : 1761 ( val = elem.getAttributeNode( name ) ) && val.specified ? 1762 val.value : 1763 null; 1764}; 1765 1766Sizzle.escape = function( sel ) { 1767 return ( sel + "" ).replace( rcssescape, fcssescape ); 1768}; 1769 1770Sizzle.error = function( msg ) { 1771 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1772}; 1773 1774/** 1775 * Document sorting and removing duplicates 1776 * @param {ArrayLike} results 1777 */ 1778Sizzle.uniqueSort = function( results ) { 1779 var elem, 1780 duplicates = [], 1781 j = 0, 1782 i = 0; 1783 1784 // Unless we *know* we can detect duplicates, assume their presence 1785 hasDuplicate = !support.detectDuplicates; 1786 sortInput = !support.sortStable && results.slice( 0 ); 1787 results.sort( sortOrder ); 1788 1789 if ( hasDuplicate ) { 1790 while ( ( elem = results[ i++ ] ) ) { 1791 if ( elem === results[ i ] ) { 1792 j = duplicates.push( i ); 1793 } 1794 } 1795 while ( j-- ) { 1796 results.splice( duplicates[ j ], 1 ); 1797 } 1798 } 1799 1800 // Clear input after sorting to release objects 1801 // See https://github.com/jquery/sizzle/pull/225 1802 sortInput = null; 1803 1804 return results; 1805}; 1806 1807/** 1808 * Utility function for retrieving the text value of an array of DOM nodes 1809 * @param {Array|Element} elem 1810 */ 1811getText = Sizzle.getText = function( elem ) { 1812 var node, 1813 ret = "", 1814 i = 0, 1815 nodeType = elem.nodeType; 1816 1817 if ( !nodeType ) { 1818 1819 // If no nodeType, this is expected to be an array 1820 while ( ( node = elem[ i++ ] ) ) { 1821 1822 // Do not traverse comment nodes 1823 ret += getText( node ); 1824 } 1825 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 1826 1827 // Use textContent for elements 1828 // innerText usage removed for consistency of new lines (jQuery #11153) 1829 if ( typeof elem.textContent === "string" ) { 1830 return elem.textContent; 1831 } else { 1832 1833 // Traverse its children 1834 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1835 ret += getText( elem ); 1836 } 1837 } 1838 } else if ( nodeType === 3 || nodeType === 4 ) { 1839 return elem.nodeValue; 1840 } 1841 1842 // Do not include comment or processing instruction nodes 1843 1844 return ret; 1845}; 1846 1847Expr = Sizzle.selectors = { 1848 1849 // Can be adjusted by the user 1850 cacheLength: 50, 1851 1852 createPseudo: markFunction, 1853 1854 match: matchExpr, 1855 1856 attrHandle: {}, 1857 1858 find: {}, 1859 1860 relative: { 1861 ">": { dir: "parentNode", first: true }, 1862 " ": { dir: "parentNode" }, 1863 "+": { dir: "previousSibling", first: true }, 1864 "~": { dir: "previousSibling" } 1865 }, 1866 1867 preFilter: { 1868 "ATTR": function( match ) { 1869 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 1870 1871 // Move the given value to match[3] whether quoted or unquoted 1872 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || 1873 match[ 5 ] || "" ).replace( runescape, funescape ); 1874 1875 if ( match[ 2 ] === "~=" ) { 1876 match[ 3 ] = " " + match[ 3 ] + " "; 1877 } 1878 1879 return match.slice( 0, 4 ); 1880 }, 1881 1882 "CHILD": function( match ) { 1883 1884 /* matches from matchExpr["CHILD"] 1885 1 type (only|nth|...) 1886 2 what (child|of-type) 1887 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1888 4 xn-component of xn+y argument ([+-]?\d*n|) 1889 5 sign of xn-component 1890 6 x of xn-component 1891 7 sign of y-component 1892 8 y of y-component 1893 */ 1894 match[ 1 ] = match[ 1 ].toLowerCase(); 1895 1896 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 1897 1898 // nth-* requires argument 1899 if ( !match[ 3 ] ) { 1900 Sizzle.error( match[ 0 ] ); 1901 } 1902 1903 // numeric x and y parameters for Expr.filter.CHILD 1904 // remember that false/true cast respectively to 0/1 1905 match[ 4 ] = +( match[ 4 ] ? 1906 match[ 5 ] + ( match[ 6 ] || 1 ) : 1907 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); 1908 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 1909 1910 // other types prohibit arguments 1911 } else if ( match[ 3 ] ) { 1912 Sizzle.error( match[ 0 ] ); 1913 } 1914 1915 return match; 1916 }, 1917 1918 "PSEUDO": function( match ) { 1919 var excess, 1920 unquoted = !match[ 6 ] && match[ 2 ]; 1921 1922 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { 1923 return null; 1924 } 1925 1926 // Accept quoted arguments as-is 1927 if ( match[ 3 ] ) { 1928 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 1929 1930 // Strip excess characters from unquoted arguments 1931 } else if ( unquoted && rpseudo.test( unquoted ) && 1932 1933 // Get excess from tokenize (recursively) 1934 ( excess = tokenize( unquoted, true ) ) && 1935 1936 // advance to the next closing parenthesis 1937 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 1938 1939 // excess is a negative index 1940 match[ 0 ] = match[ 0 ].slice( 0, excess ); 1941 match[ 2 ] = unquoted.slice( 0, excess ); 1942 } 1943 1944 // Return only captures needed by the pseudo filter method (type and argument) 1945 return match.slice( 0, 3 ); 1946 } 1947 }, 1948 1949 filter: { 1950 1951 "TAG": function( nodeNameSelector ) { 1952 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1953 return nodeNameSelector === "*" ? 1954 function() { 1955 return true; 1956 } : 1957 function( elem ) { 1958 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 1959 }; 1960 }, 1961 1962 "CLASS": function( className ) { 1963 var pattern = classCache[ className + " " ]; 1964 1965 return pattern || 1966 ( pattern = new RegExp( "(^|" + whitespace + 1967 ")" + className + "(" + whitespace + "|$)" ) ) && classCache( 1968 className, function( elem ) { 1969 return pattern.test( 1970 typeof elem.className === "string" && elem.className || 1971 typeof elem.getAttribute !== "undefined" && 1972 elem.getAttribute( "class" ) || 1973 "" 1974 ); 1975 } ); 1976 }, 1977 1978 "ATTR": function( name, operator, check ) { 1979 return function( elem ) { 1980 var result = Sizzle.attr( elem, name ); 1981 1982 if ( result == null ) { 1983 return operator === "!="; 1984 } 1985 if ( !operator ) { 1986 return true; 1987 } 1988 1989 result += ""; 1990 1991 /* eslint-disable max-len */ 1992 1993 return operator === "=" ? result === check : 1994 operator === "!=" ? result !== check : 1995 operator === "^=" ? check && result.indexOf( check ) === 0 : 1996 operator === "*=" ? check && result.indexOf( check ) > -1 : 1997 operator === "$=" ? check && result.slice( -check.length ) === check : 1998 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 1999 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 2000 false; 2001 /* eslint-enable max-len */ 2002 2003 }; 2004 }, 2005 2006 "CHILD": function( type, what, _argument, first, last ) { 2007 var simple = type.slice( 0, 3 ) !== "nth", 2008 forward = type.slice( -4 ) !== "last", 2009 ofType = what === "of-type"; 2010 2011 return first === 1 && last === 0 ? 2012 2013 // Shortcut for :nth-*(n) 2014 function( elem ) { 2015 return !!elem.parentNode; 2016 } : 2017 2018 function( elem, _context, xml ) { 2019 var cache, uniqueCache, outerCache, node, nodeIndex, start, 2020 dir = simple !== forward ? "nextSibling" : "previousSibling", 2021 parent = elem.parentNode, 2022 name = ofType && elem.nodeName.toLowerCase(), 2023 useCache = !xml && !ofType, 2024 diff = false; 2025 2026 if ( parent ) { 2027 2028 // :(first|last|only)-(child|of-type) 2029 if ( simple ) { 2030 while ( dir ) { 2031 node = elem; 2032 while ( ( node = node[ dir ] ) ) { 2033 if ( ofType ? 2034 node.nodeName.toLowerCase() === name : 2035 node.nodeType === 1 ) { 2036 2037 return false; 2038 } 2039 } 2040 2041 // Reverse direction for :only-* (if we haven't yet done so) 2042 start = dir = type === "only" && !start && "nextSibling"; 2043 } 2044 return true; 2045 } 2046 2047 start = [ forward ? parent.firstChild : parent.lastChild ]; 2048 2049 // non-xml :nth-child(...) stores cache data on `parent` 2050 if ( forward && useCache ) { 2051 2052 // Seek `elem` from a previously-cached index 2053 2054 // ...in a gzip-friendly way 2055 node = parent; 2056 outerCache = node[ expando ] || ( node[ expando ] = {} ); 2057 2058 // Support: IE <9 only 2059 // Defend against cloned attroperties (jQuery gh-1709) 2060 uniqueCache = outerCache[ node.uniqueID ] || 2061 ( outerCache[ node.uniqueID ] = {} ); 2062 2063 cache = uniqueCache[ type ] || []; 2064 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 2065 diff = nodeIndex && cache[ 2 ]; 2066 node = nodeIndex && parent.childNodes[ nodeIndex ]; 2067 2068 while ( ( node = ++nodeIndex && node && node[ dir ] || 2069 2070 // Fallback to seeking `elem` from the start 2071 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 2072 2073 // When found, cache indexes on `parent` and break 2074 if ( node.nodeType === 1 && ++diff && node === elem ) { 2075 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 2076 break; 2077 } 2078 } 2079 2080 } else { 2081 2082 // Use previously-cached element index if available 2083 if ( useCache ) { 2084 2085 // ...in a gzip-friendly way 2086 node = elem; 2087 outerCache = node[ expando ] || ( node[ expando ] = {} ); 2088 2089 // Support: IE <9 only 2090 // Defend against cloned attroperties (jQuery gh-1709) 2091 uniqueCache = outerCache[ node.uniqueID ] || 2092 ( outerCache[ node.uniqueID ] = {} ); 2093 2094 cache = uniqueCache[ type ] || []; 2095 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 2096 diff = nodeIndex; 2097 } 2098 2099 // xml :nth-child(...) 2100 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 2101 if ( diff === false ) { 2102 2103 // Use the same loop as above to seek `elem` from the start 2104 while ( ( node = ++nodeIndex && node && node[ dir ] || 2105 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 2106 2107 if ( ( ofType ? 2108 node.nodeName.toLowerCase() === name : 2109 node.nodeType === 1 ) && 2110 ++diff ) { 2111 2112 // Cache the index of each encountered element 2113 if ( useCache ) { 2114 outerCache = node[ expando ] || 2115 ( node[ expando ] = {} ); 2116 2117 // Support: IE <9 only 2118 // Defend against cloned attroperties (jQuery gh-1709) 2119 uniqueCache = outerCache[ node.uniqueID ] || 2120 ( outerCache[ node.uniqueID ] = {} ); 2121 2122 uniqueCache[ type ] = [ dirruns, diff ]; 2123 } 2124 2125 if ( node === elem ) { 2126 break; 2127 } 2128 } 2129 } 2130 } 2131 } 2132 2133 // Incorporate the offset, then check against cycle size 2134 diff -= last; 2135 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 2136 } 2137 }; 2138 }, 2139 2140 "PSEUDO": function( pseudo, argument ) { 2141 2142 // pseudo-class names are case-insensitive 2143 // http://www.w3.org/TR/selectors/#pseudo-classes 2144 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 2145 // Remember that setFilters inherits from pseudos 2146 var args, 2147 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 2148 Sizzle.error( "unsupported pseudo: " + pseudo ); 2149 2150 // The user may use createPseudo to indicate that 2151 // arguments are needed to create the filter function 2152 // just as Sizzle does 2153 if ( fn[ expando ] ) { 2154 return fn( argument ); 2155 } 2156 2157 // But maintain support for old signatures 2158 if ( fn.length > 1 ) { 2159 args = [ pseudo, pseudo, "", argument ]; 2160 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 2161 markFunction( function( seed, matches ) { 2162 var idx, 2163 matched = fn( seed, argument ), 2164 i = matched.length; 2165 while ( i-- ) { 2166 idx = indexOf( seed, matched[ i ] ); 2167 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 2168 } 2169 } ) : 2170 function( elem ) { 2171 return fn( elem, 0, args ); 2172 }; 2173 } 2174 2175 return fn; 2176 } 2177 }, 2178 2179 pseudos: { 2180 2181 // Potentially complex pseudos 2182 "not": markFunction( function( selector ) { 2183 2184 // Trim the selector passed to compile 2185 // to avoid treating leading and trailing 2186 // spaces as combinators 2187 var input = [], 2188 results = [], 2189 matcher = compile( selector.replace( rtrim, "$1" ) ); 2190 2191 return matcher[ expando ] ? 2192 markFunction( function( seed, matches, _context, xml ) { 2193 var elem, 2194 unmatched = matcher( seed, null, xml, [] ), 2195 i = seed.length; 2196 2197 // Match elements unmatched by `matcher` 2198 while ( i-- ) { 2199 if ( ( elem = unmatched[ i ] ) ) { 2200 seed[ i ] = !( matches[ i ] = elem ); 2201 } 2202 } 2203 } ) : 2204 function( elem, _context, xml ) { 2205 input[ 0 ] = elem; 2206 matcher( input, null, xml, results ); 2207 2208 // Don't keep the element (issue #299) 2209 input[ 0 ] = null; 2210 return !results.pop(); 2211 }; 2212 } ), 2213 2214 "has": markFunction( function( selector ) { 2215 return function( elem ) { 2216 return Sizzle( selector, elem ).length > 0; 2217 }; 2218 } ), 2219 2220 "contains": markFunction( function( text ) { 2221 text = text.replace( runescape, funescape ); 2222 return function( elem ) { 2223 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; 2224 }; 2225 } ), 2226 2227 // "Whether an element is represented by a :lang() selector 2228 // is based solely on the element's language value 2229 // being equal to the identifier C, 2230 // or beginning with the identifier C immediately followed by "-". 2231 // The matching of C against the element's language value is performed case-insensitively. 2232 // The identifier C does not have to be a valid language name." 2233 // http://www.w3.org/TR/selectors/#lang-pseudo 2234 "lang": markFunction( function( lang ) { 2235 2236 // lang value must be a valid identifier 2237 if ( !ridentifier.test( lang || "" ) ) { 2238 Sizzle.error( "unsupported lang: " + lang ); 2239 } 2240 lang = lang.replace( runescape, funescape ).toLowerCase(); 2241 return function( elem ) { 2242 var elemLang; 2243 do { 2244 if ( ( elemLang = documentIsHTML ? 2245 elem.lang : 2246 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 2247 2248 elemLang = elemLang.toLowerCase(); 2249 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 2250 } 2251 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 2252 return false; 2253 }; 2254 } ), 2255 2256 // Miscellaneous 2257 "target": function( elem ) { 2258 var hash = window.location && window.location.hash; 2259 return hash && hash.slice( 1 ) === elem.id; 2260 }, 2261 2262 "root": function( elem ) { 2263 return elem === docElem; 2264 }, 2265 2266 "focus": function( elem ) { 2267 return elem === document.activeElement && 2268 ( !document.hasFocus || document.hasFocus() ) && 2269 !!( elem.type || elem.href || ~elem.tabIndex ); 2270 }, 2271 2272 // Boolean properties 2273 "enabled": createDisabledPseudo( false ), 2274 "disabled": createDisabledPseudo( true ), 2275 2276 "checked": function( elem ) { 2277 2278 // In CSS3, :checked should return both checked and selected elements 2279 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 2280 var nodeName = elem.nodeName.toLowerCase(); 2281 return ( nodeName === "input" && !!elem.checked ) || 2282 ( nodeName === "option" && !!elem.selected ); 2283 }, 2284 2285 "selected": function( elem ) { 2286 2287 // Accessing this property makes selected-by-default 2288 // options in Safari work properly 2289 if ( elem.parentNode ) { 2290 // eslint-disable-next-line no-unused-expressions 2291 elem.parentNode.selectedIndex; 2292 } 2293 2294 return elem.selected === true; 2295 }, 2296 2297 // Contents 2298 "empty": function( elem ) { 2299 2300 // http://www.w3.org/TR/selectors/#empty-pseudo 2301 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 2302 // but not by others (comment: 8; processing instruction: 7; etc.) 2303 // nodeType < 6 works because attributes (2) do not appear as children 2304 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 2305 if ( elem.nodeType < 6 ) { 2306 return false; 2307 } 2308 } 2309 return true; 2310 }, 2311 2312 "parent": function( elem ) { 2313 return !Expr.pseudos[ "empty" ]( elem ); 2314 }, 2315 2316 // Element/input types 2317 "header": function( elem ) { 2318 return rheader.test( elem.nodeName ); 2319 }, 2320 2321 "input": function( elem ) { 2322 return rinputs.test( elem.nodeName ); 2323 }, 2324 2325 "button": function( elem ) { 2326 var name = elem.nodeName.toLowerCase(); 2327 return name === "input" && elem.type === "button" || name === "button"; 2328 }, 2329 2330 "text": function( elem ) { 2331 var attr; 2332 return elem.nodeName.toLowerCase() === "input" && 2333 elem.type === "text" && 2334 2335 // Support: IE<8 2336 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 2337 ( ( attr = elem.getAttribute( "type" ) ) == null || 2338 attr.toLowerCase() === "text" ); 2339 }, 2340 2341 // Position-in-collection 2342 "first": createPositionalPseudo( function() { 2343 return [ 0 ]; 2344 } ), 2345 2346 "last": createPositionalPseudo( function( _matchIndexes, length ) { 2347 return [ length - 1 ]; 2348 } ), 2349 2350 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { 2351 return [ argument < 0 ? argument + length : argument ]; 2352 } ), 2353 2354 "even": createPositionalPseudo( function( matchIndexes, length ) { 2355 var i = 0; 2356 for ( ; i < length; i += 2 ) { 2357 matchIndexes.push( i ); 2358 } 2359 return matchIndexes; 2360 } ), 2361 2362 "odd": createPositionalPseudo( function( matchIndexes, length ) { 2363 var i = 1; 2364 for ( ; i < length; i += 2 ) { 2365 matchIndexes.push( i ); 2366 } 2367 return matchIndexes; 2368 } ), 2369 2370 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { 2371 var i = argument < 0 ? 2372 argument + length : 2373 argument > length ? 2374 length : 2375 argument; 2376 for ( ; --i >= 0; ) { 2377 matchIndexes.push( i ); 2378 } 2379 return matchIndexes; 2380 } ), 2381 2382 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { 2383 var i = argument < 0 ? argument + length : argument; 2384 for ( ; ++i < length; ) { 2385 matchIndexes.push( i ); 2386 } 2387 return matchIndexes; 2388 } ) 2389 } 2390}; 2391 2392Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; 2393 2394// Add button/input type pseudos 2395for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2396 Expr.pseudos[ i ] = createInputPseudo( i ); 2397} 2398for ( i in { submit: true, reset: true } ) { 2399 Expr.pseudos[ i ] = createButtonPseudo( i ); 2400} 2401 2402// Easy API for creating new setFilters 2403function setFilters() {} 2404setFilters.prototype = Expr.filters = Expr.pseudos; 2405Expr.setFilters = new setFilters(); 2406 2407tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 2408 var matched, match, tokens, type, 2409 soFar, groups, preFilters, 2410 cached = tokenCache[ selector + " " ]; 2411 2412 if ( cached ) { 2413 return parseOnly ? 0 : cached.slice( 0 ); 2414 } 2415 2416 soFar = selector; 2417 groups = []; 2418 preFilters = Expr.preFilter; 2419 2420 while ( soFar ) { 2421 2422 // Comma and first run 2423 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 2424 if ( match ) { 2425 2426 // Don't consume trailing commas as valid 2427 soFar = soFar.slice( match[ 0 ].length ) || soFar; 2428 } 2429 groups.push( ( tokens = [] ) ); 2430 } 2431 2432 matched = false; 2433 2434 // Combinators 2435 if ( ( match = rcombinators.exec( soFar ) ) ) { 2436 matched = match.shift(); 2437 tokens.push( { 2438 value: matched, 2439 2440 // Cast descendant combinators to space 2441 type: match[ 0 ].replace( rtrim, " " ) 2442 } ); 2443 soFar = soFar.slice( matched.length ); 2444 } 2445 2446 // Filters 2447 for ( type in Expr.filter ) { 2448 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 2449 ( match = preFilters[ type ]( match ) ) ) ) { 2450 matched = match.shift(); 2451 tokens.push( { 2452 value: matched, 2453 type: type, 2454 matches: match 2455 } ); 2456 soFar = soFar.slice( matched.length ); 2457 } 2458 } 2459 2460 if ( !matched ) { 2461 break; 2462 } 2463 } 2464 2465 // Return the length of the invalid excess 2466 // if we're just parsing 2467 // Otherwise, throw an error or return tokens 2468 return parseOnly ? 2469 soFar.length : 2470 soFar ? 2471 Sizzle.error( selector ) : 2472 2473 // Cache the tokens 2474 tokenCache( selector, groups ).slice( 0 ); 2475}; 2476 2477function toSelector( tokens ) { 2478 var i = 0, 2479 len = tokens.length, 2480 selector = ""; 2481 for ( ; i < len; i++ ) { 2482 selector += tokens[ i ].value; 2483 } 2484 return selector; 2485} 2486 2487function addCombinator( matcher, combinator, base ) { 2488 var dir = combinator.dir, 2489 skip = combinator.next, 2490 key = skip || dir, 2491 checkNonElements = base && key === "parentNode", 2492 doneName = done++; 2493 2494 return combinator.first ? 2495 2496 // Check against closest ancestor/preceding element 2497 function( elem, context, xml ) { 2498 while ( ( elem = elem[ dir ] ) ) { 2499 if ( elem.nodeType === 1 || checkNonElements ) { 2500 return matcher( elem, context, xml ); 2501 } 2502 } 2503 return false; 2504 } : 2505 2506 // Check against all ancestor/preceding elements 2507 function( elem, context, xml ) { 2508 var oldCache, uniqueCache, outerCache, 2509 newCache = [ dirruns, doneName ]; 2510 2511 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2512 if ( xml ) { 2513 while ( ( elem = elem[ dir ] ) ) { 2514 if ( elem.nodeType === 1 || checkNonElements ) { 2515 if ( matcher( elem, context, xml ) ) { 2516 return true; 2517 } 2518 } 2519 } 2520 } else { 2521 while ( ( elem = elem[ dir ] ) ) { 2522 if ( elem.nodeType === 1 || checkNonElements ) { 2523 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 2524 2525 // Support: IE <9 only 2526 // Defend against cloned attroperties (jQuery gh-1709) 2527 uniqueCache = outerCache[ elem.uniqueID ] || 2528 ( outerCache[ elem.uniqueID ] = {} ); 2529 2530 if ( skip && skip === elem.nodeName.toLowerCase() ) { 2531 elem = elem[ dir ] || elem; 2532 } else if ( ( oldCache = uniqueCache[ key ] ) && 2533 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2534 2535 // Assign to newCache so results back-propagate to previous elements 2536 return ( newCache[ 2 ] = oldCache[ 2 ] ); 2537 } else { 2538 2539 // Reuse newcache so results back-propagate to previous elements 2540 uniqueCache[ key ] = newCache; 2541 2542 // A match means we're done; a fail means we have to keep checking 2543 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 2544 return true; 2545 } 2546 } 2547 } 2548 } 2549 } 2550 return false; 2551 }; 2552} 2553 2554function elementMatcher( matchers ) { 2555 return matchers.length > 1 ? 2556 function( elem, context, xml ) { 2557 var i = matchers.length; 2558 while ( i-- ) { 2559 if ( !matchers[ i ]( elem, context, xml ) ) { 2560 return false; 2561 } 2562 } 2563 return true; 2564 } : 2565 matchers[ 0 ]; 2566} 2567 2568function multipleContexts( selector, contexts, results ) { 2569 var i = 0, 2570 len = contexts.length; 2571 for ( ; i < len; i++ ) { 2572 Sizzle( selector, contexts[ i ], results ); 2573 } 2574 return results; 2575} 2576 2577function condense( unmatched, map, filter, context, xml ) { 2578 var elem, 2579 newUnmatched = [], 2580 i = 0, 2581 len = unmatched.length, 2582 mapped = map != null; 2583 2584 for ( ; i < len; i++ ) { 2585 if ( ( elem = unmatched[ i ] ) ) { 2586 if ( !filter || filter( elem, context, xml ) ) { 2587 newUnmatched.push( elem ); 2588 if ( mapped ) { 2589 map.push( i ); 2590 } 2591 } 2592 } 2593 } 2594 2595 return newUnmatched; 2596} 2597 2598function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2599 if ( postFilter && !postFilter[ expando ] ) { 2600 postFilter = setMatcher( postFilter ); 2601 } 2602 if ( postFinder && !postFinder[ expando ] ) { 2603 postFinder = setMatcher( postFinder, postSelector ); 2604 } 2605 return markFunction( function( seed, results, context, xml ) { 2606 var temp, i, elem, 2607 preMap = [], 2608 postMap = [], 2609 preexisting = results.length, 2610 2611 // Get initial elements from seed or context 2612 elems = seed || multipleContexts( 2613 selector || "*", 2614 context.nodeType ? [ context ] : context, 2615 [] 2616 ), 2617 2618 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2619 matcherIn = preFilter && ( seed || !selector ) ? 2620 condense( elems, preMap, preFilter, context, xml ) : 2621 elems, 2622 2623 matcherOut = matcher ? 2624 2625 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 2626 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2627 2628 // ...intermediate processing is necessary 2629 [] : 2630 2631 // ...otherwise use results directly 2632 results : 2633 matcherIn; 2634 2635 // Find primary matches 2636 if ( matcher ) { 2637 matcher( matcherIn, matcherOut, context, xml ); 2638 } 2639 2640 // Apply postFilter 2641 if ( postFilter ) { 2642 temp = condense( matcherOut, postMap ); 2643 postFilter( temp, [], context, xml ); 2644 2645 // Un-match failing elements by moving them back to matcherIn 2646 i = temp.length; 2647 while ( i-- ) { 2648 if ( ( elem = temp[ i ] ) ) { 2649 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 2650 } 2651 } 2652 } 2653 2654 if ( seed ) { 2655 if ( postFinder || preFilter ) { 2656 if ( postFinder ) { 2657 2658 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2659 temp = []; 2660 i = matcherOut.length; 2661 while ( i-- ) { 2662 if ( ( elem = matcherOut[ i ] ) ) { 2663 2664 // Restore matcherIn since elem is not yet a final match 2665 temp.push( ( matcherIn[ i ] = elem ) ); 2666 } 2667 } 2668 postFinder( null, ( matcherOut = [] ), temp, xml ); 2669 } 2670 2671 // Move matched elements from seed to results to keep them synchronized 2672 i = matcherOut.length; 2673 while ( i-- ) { 2674 if ( ( elem = matcherOut[ i ] ) && 2675 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { 2676 2677 seed[ temp ] = !( results[ temp ] = elem ); 2678 } 2679 } 2680 } 2681 2682 // Add elements to results, through postFinder if defined 2683 } else { 2684 matcherOut = condense( 2685 matcherOut === results ? 2686 matcherOut.splice( preexisting, matcherOut.length ) : 2687 matcherOut 2688 ); 2689 if ( postFinder ) { 2690 postFinder( null, results, matcherOut, xml ); 2691 } else { 2692 push.apply( results, matcherOut ); 2693 } 2694 } 2695 } ); 2696} 2697 2698function matcherFromTokens( tokens ) { 2699 var checkContext, matcher, j, 2700 len = tokens.length, 2701 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 2702 implicitRelative = leadingRelative || Expr.relative[ " " ], 2703 i = leadingRelative ? 1 : 0, 2704 2705 // The foundational matcher ensures that elements are reachable from top-level context(s) 2706 matchContext = addCombinator( function( elem ) { 2707 return elem === checkContext; 2708 }, implicitRelative, true ), 2709 matchAnyContext = addCombinator( function( elem ) { 2710 return indexOf( checkContext, elem ) > -1; 2711 }, implicitRelative, true ), 2712 matchers = [ function( elem, context, xml ) { 2713 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 2714 ( checkContext = context ).nodeType ? 2715 matchContext( elem, context, xml ) : 2716 matchAnyContext( elem, context, xml ) ); 2717 2718 // Avoid hanging onto element (issue #299) 2719 checkContext = null; 2720 return ret; 2721 } ]; 2722 2723 for ( ; i < len; i++ ) { 2724 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 2725 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 2726 } else { 2727 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 2728 2729 // Return special upon seeing a positional matcher 2730 if ( matcher[ expando ] ) { 2731 2732 // Find the next relative operator (if any) for proper handling 2733 j = ++i; 2734 for ( ; j < len; j++ ) { 2735 if ( Expr.relative[ tokens[ j ].type ] ) { 2736 break; 2737 } 2738 } 2739 return setMatcher( 2740 i > 1 && elementMatcher( matchers ), 2741 i > 1 && toSelector( 2742 2743 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2744 tokens 2745 .slice( 0, i - 1 ) 2746 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 2747 ).replace( rtrim, "$1" ), 2748 matcher, 2749 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2750 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 2751 j < len && toSelector( tokens ) 2752 ); 2753 } 2754 matchers.push( matcher ); 2755 } 2756 } 2757 2758 return elementMatcher( matchers ); 2759} 2760 2761function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2762 var bySet = setMatchers.length > 0, 2763 byElement = elementMatchers.length > 0, 2764 superMatcher = function( seed, context, xml, results, outermost ) { 2765 var elem, j, matcher, 2766 matchedCount = 0, 2767 i = "0", 2768 unmatched = seed && [], 2769 setMatched = [], 2770 contextBackup = outermostContext, 2771 2772 // We must always have either seed elements or outermost context 2773 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), 2774 2775 // Use integer dirruns iff this is the outermost matcher 2776 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 2777 len = elems.length; 2778 2779 if ( outermost ) { 2780 2781 // Support: IE 11+, Edge 17 - 18+ 2782 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2783 // two documents; shallow comparisons work. 2784 // eslint-disable-next-line eqeqeq 2785 outermostContext = context == document || context || outermost; 2786 } 2787 2788 // Add elements passing elementMatchers directly to results 2789 // Support: IE<9, Safari 2790 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 2791 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 2792 if ( byElement && elem ) { 2793 j = 0; 2794 2795 // Support: IE 11+, Edge 17 - 18+ 2796 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2797 // two documents; shallow comparisons work. 2798 // eslint-disable-next-line eqeqeq 2799 if ( !context && elem.ownerDocument != document ) { 2800 setDocument( elem ); 2801 xml = !documentIsHTML; 2802 } 2803 while ( ( matcher = elementMatchers[ j++ ] ) ) { 2804 if ( matcher( elem, context || document, xml ) ) { 2805 results.push( elem ); 2806 break; 2807 } 2808 } 2809 if ( outermost ) { 2810 dirruns = dirrunsUnique; 2811 } 2812 } 2813 2814 // Track unmatched elements for set filters 2815 if ( bySet ) { 2816 2817 // They will have gone through all possible matchers 2818 if ( ( elem = !matcher && elem ) ) { 2819 matchedCount--; 2820 } 2821 2822 // Lengthen the array for every element, matched or not 2823 if ( seed ) { 2824 unmatched.push( elem ); 2825 } 2826 } 2827 } 2828 2829 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2830 // makes the latter nonnegative. 2831 matchedCount += i; 2832 2833 // Apply set filters to unmatched elements 2834 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2835 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2836 // no element matchers and no seed. 2837 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2838 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2839 // numerically zero. 2840 if ( bySet && i !== matchedCount ) { 2841 j = 0; 2842 while ( ( matcher = setMatchers[ j++ ] ) ) { 2843 matcher( unmatched, setMatched, context, xml ); 2844 } 2845 2846 if ( seed ) { 2847 2848 // Reintegrate element matches to eliminate the need for sorting 2849 if ( matchedCount > 0 ) { 2850 while ( i-- ) { 2851 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 2852 setMatched[ i ] = pop.call( results ); 2853 } 2854 } 2855 } 2856 2857 // Discard index placeholder values to get only actual matches 2858 setMatched = condense( setMatched ); 2859 } 2860 2861 // Add matches to results 2862 push.apply( results, setMatched ); 2863 2864 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2865 if ( outermost && !seed && setMatched.length > 0 && 2866 ( matchedCount + setMatchers.length ) > 1 ) { 2867 2868 Sizzle.uniqueSort( results ); 2869 } 2870 } 2871 2872 // Override manipulation of globals by nested matchers 2873 if ( outermost ) { 2874 dirruns = dirrunsUnique; 2875 outermostContext = contextBackup; 2876 } 2877 2878 return unmatched; 2879 }; 2880 2881 return bySet ? 2882 markFunction( superMatcher ) : 2883 superMatcher; 2884} 2885 2886compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 2887 var i, 2888 setMatchers = [], 2889 elementMatchers = [], 2890 cached = compilerCache[ selector + " " ]; 2891 2892 if ( !cached ) { 2893 2894 // Generate a function of recursive functions that can be used to check each element 2895 if ( !match ) { 2896 match = tokenize( selector ); 2897 } 2898 i = match.length; 2899 while ( i-- ) { 2900 cached = matcherFromTokens( match[ i ] ); 2901 if ( cached[ expando ] ) { 2902 setMatchers.push( cached ); 2903 } else { 2904 elementMatchers.push( cached ); 2905 } 2906 } 2907 2908 // Cache the compiled function 2909 cached = compilerCache( 2910 selector, 2911 matcherFromGroupMatchers( elementMatchers, setMatchers ) 2912 ); 2913 2914 // Save selector and tokenization 2915 cached.selector = selector; 2916 } 2917 return cached; 2918}; 2919 2920/** 2921 * A low-level selection function that works with Sizzle's compiled 2922 * selector functions 2923 * @param {String|Function} selector A selector or a pre-compiled 2924 * selector function built with Sizzle.compile 2925 * @param {Element} context 2926 * @param {Array} [results] 2927 * @param {Array} [seed] A set of elements to match against 2928 */ 2929select = Sizzle.select = function( selector, context, results, seed ) { 2930 var i, tokens, token, type, find, 2931 compiled = typeof selector === "function" && selector, 2932 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 2933 2934 results = results || []; 2935 2936 // Try to minimize operations if there is only one selector in the list and no seed 2937 // (the latter of which guarantees us context) 2938 if ( match.length === 1 ) { 2939 2940 // Reduce context if the leading compound selector is an ID 2941 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 2942 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 2943 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 2944 2945 context = ( Expr.find[ "ID" ]( token.matches[ 0 ] 2946 .replace( runescape, funescape ), context ) || [] )[ 0 ]; 2947 if ( !context ) { 2948 return results; 2949 2950 // Precompiled matchers will still verify ancestry, so step up a level 2951 } else if ( compiled ) { 2952 context = context.parentNode; 2953 } 2954 2955 selector = selector.slice( tokens.shift().value.length ); 2956 } 2957 2958 // Fetch a seed set for right-to-left matching 2959 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; 2960 while ( i-- ) { 2961 token = tokens[ i ]; 2962 2963 // Abort if we hit a combinator 2964 if ( Expr.relative[ ( type = token.type ) ] ) { 2965 break; 2966 } 2967 if ( ( find = Expr.find[ type ] ) ) { 2968 2969 // Search, expanding context for leading sibling combinators 2970 if ( ( seed = find( 2971 token.matches[ 0 ].replace( runescape, funescape ), 2972 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || 2973 context 2974 ) ) ) { 2975 2976 // If seed is empty or no tokens remain, we can return early 2977 tokens.splice( i, 1 ); 2978 selector = seed.length && toSelector( tokens ); 2979 if ( !selector ) { 2980 push.apply( results, seed ); 2981 return results; 2982 } 2983 2984 break; 2985 } 2986 } 2987 } 2988 } 2989 2990 // Compile and execute a filtering function if one is not provided 2991 // Provide `match` to avoid retokenization if we modified the selector above 2992 ( compiled || compile( selector, match ) )( 2993 seed, 2994 context, 2995 !documentIsHTML, 2996 results, 2997 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2998 ); 2999 return results; 3000}; 3001 3002// One-time assignments 3003 3004// Sort stability 3005support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 3006 3007// Support: Chrome 14-35+ 3008// Always assume duplicates if they aren't passed to the comparison function 3009support.detectDuplicates = !!hasDuplicate; 3010 3011// Initialize against the default document 3012setDocument(); 3013 3014// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 3015// Detached nodes confoundingly follow *each other* 3016support.sortDetached = assert( function( el ) { 3017 3018 // Should return 1, but returns 4 (following) 3019 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 3020} ); 3021 3022// Support: IE<8 3023// Prevent attribute/property "interpolation" 3024// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 3025if ( !assert( function( el ) { 3026 el.innerHTML = "<a href='#'></a>"; 3027 return el.firstChild.getAttribute( "href" ) === "#"; 3028} ) ) { 3029 addHandle( "type|href|height|width", function( elem, name, isXML ) { 3030 if ( !isXML ) { 3031 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 3032 } 3033 } ); 3034} 3035 3036// Support: IE<9 3037// Use defaultValue in place of getAttribute("value") 3038if ( !support.attributes || !assert( function( el ) { 3039 el.innerHTML = "<input/>"; 3040 el.firstChild.setAttribute( "value", "" ); 3041 return el.firstChild.getAttribute( "value" ) === ""; 3042} ) ) { 3043 addHandle( "value", function( elem, _name, isXML ) { 3044 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 3045 return elem.defaultValue; 3046 } 3047 } ); 3048} 3049 3050// Support: IE<9 3051// Use getAttributeNode to fetch booleans when getAttribute lies 3052if ( !assert( function( el ) { 3053 return el.getAttribute( "disabled" ) == null; 3054} ) ) { 3055 addHandle( booleans, function( elem, name, isXML ) { 3056 var val; 3057 if ( !isXML ) { 3058 return elem[ name ] === true ? name.toLowerCase() : 3059 ( val = elem.getAttributeNode( name ) ) && val.specified ? 3060 val.value : 3061 null; 3062 } 3063 } ); 3064} 3065 3066return Sizzle; 3067 3068} )( window ); 3069 3070 3071 3072jQuery.find = Sizzle; 3073jQuery.expr = Sizzle.selectors; 3074 3075// Deprecated 3076jQuery.expr[ ":" ] = jQuery.expr.pseudos; 3077jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 3078jQuery.text = Sizzle.getText; 3079jQuery.isXMLDoc = Sizzle.isXML; 3080jQuery.contains = Sizzle.contains; 3081jQuery.escapeSelector = Sizzle.escape; 3082 3083 3084 3085 3086var dir = function( elem, dir, until ) { 3087 var matched = [], 3088 truncate = until !== undefined; 3089 3090 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 3091 if ( elem.nodeType === 1 ) { 3092 if ( truncate && jQuery( elem ).is( until ) ) { 3093 break; 3094 } 3095 matched.push( elem ); 3096 } 3097 } 3098 return matched; 3099}; 3100 3101 3102var siblings = function( n, elem ) { 3103 var matched = []; 3104 3105 for ( ; n; n = n.nextSibling ) { 3106 if ( n.nodeType === 1 && n !== elem ) { 3107 matched.push( n ); 3108 } 3109 } 3110 3111 return matched; 3112}; 3113 3114 3115var rneedsContext = jQuery.expr.match.needsContext; 3116 3117 3118 3119function nodeName( elem, name ) { 3120 3121 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 3122 3123} 3124var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 3125 3126 3127 3128// Implement the identical functionality for filter and not 3129function winnow( elements, qualifier, not ) { 3130 if ( isFunction( qualifier ) ) { 3131 return jQuery.grep( elements, function( elem, i ) { 3132 return !!qualifier.call( elem, i, elem ) !== not; 3133 } ); 3134 } 3135 3136 // Single element 3137 if ( qualifier.nodeType ) { 3138 return jQuery.grep( elements, function( elem ) { 3139 return ( elem === qualifier ) !== not; 3140 } ); 3141 } 3142 3143 // Arraylike of elements (jQuery, arguments, Array) 3144 if ( typeof qualifier !== "string" ) { 3145 return jQuery.grep( elements, function( elem ) { 3146 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 3147 } ); 3148 } 3149 3150 // Filtered directly for both simple and complex selectors 3151 return jQuery.filter( qualifier, elements, not ); 3152} 3153 3154jQuery.filter = function( expr, elems, not ) { 3155 var elem = elems[ 0 ]; 3156 3157 if ( not ) { 3158 expr = ":not(" + expr + ")"; 3159 } 3160 3161 if ( elems.length === 1 && elem.nodeType === 1 ) { 3162 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 3163 } 3164 3165 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 3166 return elem.nodeType === 1; 3167 } ) ); 3168}; 3169 3170jQuery.fn.extend( { 3171 find: function( selector ) { 3172 var i, ret, 3173 len = this.length, 3174 self = this; 3175 3176 if ( typeof selector !== "string" ) { 3177 return this.pushStack( jQuery( selector ).filter( function() { 3178 for ( i = 0; i < len; i++ ) { 3179 if ( jQuery.contains( self[ i ], this ) ) { 3180 return true; 3181 } 3182 } 3183 } ) ); 3184 } 3185 3186 ret = this.pushStack( [] ); 3187 3188 for ( i = 0; i < len; i++ ) { 3189 jQuery.find( selector, self[ i ], ret ); 3190 } 3191 3192 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 3193 }, 3194 filter: function( selector ) { 3195 return this.pushStack( winnow( this, selector || [], false ) ); 3196 }, 3197 not: function( selector ) { 3198 return this.pushStack( winnow( this, selector || [], true ) ); 3199 }, 3200 is: function( selector ) { 3201 return !!winnow( 3202 this, 3203 3204 // If this is a positional/relative selector, check membership in the returned set 3205 // so $("p:first").is("p:last") won't return true for a doc with two "p". 3206 typeof selector === "string" && rneedsContext.test( selector ) ? 3207 jQuery( selector ) : 3208 selector || [], 3209 false 3210 ).length; 3211 } 3212} ); 3213 3214 3215// Initialize a jQuery object 3216 3217 3218// A central reference to the root jQuery(document) 3219var rootjQuery, 3220 3221 // A simple way to check for HTML strings 3222 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 3223 // Strict HTML recognition (#11290: must start with <) 3224 // Shortcut simple #id case for speed 3225 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 3226 3227 init = jQuery.fn.init = function( selector, context, root ) { 3228 var match, elem; 3229 3230 // HANDLE: $(""), $(null), $(undefined), $(false) 3231 if ( !selector ) { 3232 return this; 3233 } 3234 3235 // Method init() accepts an alternate rootjQuery 3236 // so migrate can support jQuery.sub (gh-2101) 3237 root = root || rootjQuery; 3238 3239 // Handle HTML strings 3240 if ( typeof selector === "string" ) { 3241 if ( selector[ 0 ] === "<" && 3242 selector[ selector.length - 1 ] === ">" && 3243 selector.length >= 3 ) { 3244 3245 // Assume that strings that start and end with <> are HTML and skip the regex check 3246 match = [ null, selector, null ]; 3247 3248 } else { 3249 match = rquickExpr.exec( selector ); 3250 } 3251 3252 // Match html or make sure no context is specified for #id 3253 if ( match && ( match[ 1 ] || !context ) ) { 3254 3255 // HANDLE: $(html) -> $(array) 3256 if ( match[ 1 ] ) { 3257 context = context instanceof jQuery ? context[ 0 ] : context; 3258 3259 // Option to run scripts is true for back-compat 3260 // Intentionally let the error be thrown if parseHTML is not present 3261 jQuery.merge( this, jQuery.parseHTML( 3262 match[ 1 ], 3263 context && context.nodeType ? context.ownerDocument || context : document, 3264 true 3265 ) ); 3266 3267 // HANDLE: $(html, props) 3268 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 3269 for ( match in context ) { 3270 3271 // Properties of context are called as methods if possible 3272 if ( isFunction( this[ match ] ) ) { 3273 this[ match ]( context[ match ] ); 3274 3275 // ...and otherwise set as attributes 3276 } else { 3277 this.attr( match, context[ match ] ); 3278 } 3279 } 3280 } 3281 3282 return this; 3283 3284 // HANDLE: $(#id) 3285 } else { 3286 elem = document.getElementById( match[ 2 ] ); 3287 3288 if ( elem ) { 3289 3290 // Inject the element directly into the jQuery object 3291 this[ 0 ] = elem; 3292 this.length = 1; 3293 } 3294 return this; 3295 } 3296 3297 // HANDLE: $(expr, $(...)) 3298 } else if ( !context || context.jquery ) { 3299 return ( context || root ).find( selector ); 3300 3301 // HANDLE: $(expr, context) 3302 // (which is just equivalent to: $(context).find(expr) 3303 } else { 3304 return this.constructor( context ).find( selector ); 3305 } 3306 3307 // HANDLE: $(DOMElement) 3308 } else if ( selector.nodeType ) { 3309 this[ 0 ] = selector; 3310 this.length = 1; 3311 return this; 3312 3313 // HANDLE: $(function) 3314 // Shortcut for document ready 3315 } else if ( isFunction( selector ) ) { 3316 return root.ready !== undefined ? 3317 root.ready( selector ) : 3318 3319 // Execute immediately if ready is not present 3320 selector( jQuery ); 3321 } 3322 3323 return jQuery.makeArray( selector, this ); 3324 }; 3325 3326// Give the init function the jQuery prototype for later instantiation 3327init.prototype = jQuery.fn; 3328 3329// Initialize central reference 3330rootjQuery = jQuery( document ); 3331 3332 3333var rparentsprev = /^(?:parents|prev(?:Until|All))/, 3334 3335 // Methods guaranteed to produce a unique set when starting from a unique set 3336 guaranteedUnique = { 3337 children: true, 3338 contents: true, 3339 next: true, 3340 prev: true 3341 }; 3342 3343jQuery.fn.extend( { 3344 has: function( target ) { 3345 var targets = jQuery( target, this ), 3346 l = targets.length; 3347 3348 return this.filter( function() { 3349 var i = 0; 3350 for ( ; i < l; i++ ) { 3351 if ( jQuery.contains( this, targets[ i ] ) ) { 3352 return true; 3353 } 3354 } 3355 } ); 3356 }, 3357 3358 closest: function( selectors, context ) { 3359 var cur, 3360 i = 0, 3361 l = this.length, 3362 matched = [], 3363 targets = typeof selectors !== "string" && jQuery( selectors ); 3364 3365 // Positional selectors never match, since there's no _selection_ context 3366 if ( !rneedsContext.test( selectors ) ) { 3367 for ( ; i < l; i++ ) { 3368 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 3369 3370 // Always skip document fragments 3371 if ( cur.nodeType < 11 && ( targets ? 3372 targets.index( cur ) > -1 : 3373 3374 // Don't pass non-elements to Sizzle 3375 cur.nodeType === 1 && 3376 jQuery.find.matchesSelector( cur, selectors ) ) ) { 3377 3378 matched.push( cur ); 3379 break; 3380 } 3381 } 3382 } 3383 } 3384 3385 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3386 }, 3387 3388 // Determine the position of an element within the set 3389 index: function( elem ) { 3390 3391 // No argument, return index in parent 3392 if ( !elem ) { 3393 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3394 } 3395 3396 // Index in selector 3397 if ( typeof elem === "string" ) { 3398 return indexOf.call( jQuery( elem ), this[ 0 ] ); 3399 } 3400 3401 // Locate the position of the desired element 3402 return indexOf.call( this, 3403 3404 // If it receives a jQuery object, the first element is used 3405 elem.jquery ? elem[ 0 ] : elem 3406 ); 3407 }, 3408 3409 add: function( selector, context ) { 3410 return this.pushStack( 3411 jQuery.uniqueSort( 3412 jQuery.merge( this.get(), jQuery( selector, context ) ) 3413 ) 3414 ); 3415 }, 3416 3417 addBack: function( selector ) { 3418 return this.add( selector == null ? 3419 this.prevObject : this.prevObject.filter( selector ) 3420 ); 3421 } 3422} ); 3423 3424function sibling( cur, dir ) { 3425 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 3426 return cur; 3427} 3428 3429jQuery.each( { 3430 parent: function( elem ) { 3431 var parent = elem.parentNode; 3432 return parent && parent.nodeType !== 11 ? parent : null; 3433 }, 3434 parents: function( elem ) { 3435 return dir( elem, "parentNode" ); 3436 }, 3437 parentsUntil: function( elem, _i, until ) { 3438 return dir( elem, "parentNode", until ); 3439 }, 3440 next: function( elem ) { 3441 return sibling( elem, "nextSibling" ); 3442 }, 3443 prev: function( elem ) { 3444 return sibling( elem, "previousSibling" ); 3445 }, 3446 nextAll: function( elem ) { 3447 return dir( elem, "nextSibling" ); 3448 }, 3449 prevAll: function( elem ) { 3450 return dir( elem, "previousSibling" ); 3451 }, 3452 nextUntil: function( elem, _i, until ) { 3453 return dir( elem, "nextSibling", until ); 3454 }, 3455 prevUntil: function( elem, _i, until ) { 3456 return dir( elem, "previousSibling", until ); 3457 }, 3458 siblings: function( elem ) { 3459 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3460 }, 3461 children: function( elem ) { 3462 return siblings( elem.firstChild ); 3463 }, 3464 contents: function( elem ) { 3465 if ( elem.contentDocument != null && 3466 3467 // Support: IE 11+ 3468 // <object> elements with no `data` attribute has an object 3469 // `contentDocument` with a `null` prototype. 3470 getProto( elem.contentDocument ) ) { 3471 3472 return elem.contentDocument; 3473 } 3474 3475 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 3476 // Treat the template element as a regular one in browsers that 3477 // don't support it. 3478 if ( nodeName( elem, "template" ) ) { 3479 elem = elem.content || elem; 3480 } 3481 3482 return jQuery.merge( [], elem.childNodes ); 3483 } 3484}, function( name, fn ) { 3485 jQuery.fn[ name ] = function( until, selector ) { 3486 var matched = jQuery.map( this, fn, until ); 3487 3488 if ( name.slice( -5 ) !== "Until" ) { 3489 selector = until; 3490 } 3491 3492 if ( selector && typeof selector === "string" ) { 3493 matched = jQuery.filter( selector, matched ); 3494 } 3495 3496 if ( this.length > 1 ) { 3497 3498 // Remove duplicates 3499 if ( !guaranteedUnique[ name ] ) { 3500 jQuery.uniqueSort( matched ); 3501 } 3502 3503 // Reverse order for parents* and prev-derivatives 3504 if ( rparentsprev.test( name ) ) { 3505 matched.reverse(); 3506 } 3507 } 3508 3509 return this.pushStack( matched ); 3510 }; 3511} ); 3512var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 3513 3514 3515 3516// Convert String-formatted options into Object-formatted ones 3517function createOptions( options ) { 3518 var object = {}; 3519 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 3520 object[ flag ] = true; 3521 } ); 3522 return object; 3523} 3524 3525/* 3526 * Create a callback list using the following parameters: 3527 * 3528 * options: an optional list of space-separated options that will change how 3529 * the callback list behaves or a more traditional option object 3530 * 3531 * By default a callback list will act like an event callback list and can be 3532 * "fired" multiple times. 3533 * 3534 * Possible options: 3535 * 3536 * once: will ensure the callback list can only be fired once (like a Deferred) 3537 * 3538 * memory: will keep track of previous values and will call any callback added 3539 * after the list has been fired right away with the latest "memorized" 3540 * values (like a Deferred) 3541 * 3542 * unique: will ensure a callback can only be added once (no duplicate in the list) 3543 * 3544 * stopOnFalse: interrupt callings when a callback returns false 3545 * 3546 */ 3547jQuery.Callbacks = function( options ) { 3548 3549 // Convert options from String-formatted to Object-formatted if needed 3550 // (we check in cache first) 3551 options = typeof options === "string" ? 3552 createOptions( options ) : 3553 jQuery.extend( {}, options ); 3554 3555 var // Flag to know if list is currently firing 3556 firing, 3557 3558 // Last fire value for non-forgettable lists 3559 memory, 3560 3561 // Flag to know if list was already fired 3562 fired, 3563 3564 // Flag to prevent firing 3565 locked, 3566 3567 // Actual callback list 3568 list = [], 3569 3570 // Queue of execution data for repeatable lists 3571 queue = [], 3572 3573 // Index of currently firing callback (modified by add/remove as needed) 3574 firingIndex = -1, 3575 3576 // Fire callbacks 3577 fire = function() { 3578 3579 // Enforce single-firing 3580 locked = locked || options.once; 3581 3582 // Execute callbacks for all pending executions, 3583 // respecting firingIndex overrides and runtime changes 3584 fired = firing = true; 3585 for ( ; queue.length; firingIndex = -1 ) { 3586 memory = queue.shift(); 3587 while ( ++firingIndex < list.length ) { 3588 3589 // Run callback and check for early termination 3590 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 3591 options.stopOnFalse ) { 3592 3593 // Jump to end and forget the data so .add doesn't re-fire 3594 firingIndex = list.length; 3595 memory = false; 3596 } 3597 } 3598 } 3599 3600 // Forget the data if we're done with it 3601 if ( !options.memory ) { 3602 memory = false; 3603 } 3604 3605 firing = false; 3606 3607 // Clean up if we're done firing for good 3608 if ( locked ) { 3609 3610 // Keep an empty list if we have data for future add calls 3611 if ( memory ) { 3612 list = []; 3613 3614 // Otherwise, this object is spent 3615 } else { 3616 list = ""; 3617 } 3618 } 3619 }, 3620 3621 // Actual Callbacks object 3622 self = { 3623 3624 // Add a callback or a collection of callbacks to the list 3625 add: function() { 3626 if ( list ) { 3627 3628 // If we have memory from a past run, we should fire after adding 3629 if ( memory && !firing ) { 3630 firingIndex = list.length - 1; 3631 queue.push( memory ); 3632 } 3633 3634 ( function add( args ) { 3635 jQuery.each( args, function( _, arg ) { 3636 if ( isFunction( arg ) ) { 3637 if ( !options.unique || !self.has( arg ) ) { 3638 list.push( arg ); 3639 } 3640 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 3641 3642 // Inspect recursively 3643 add( arg ); 3644 } 3645 } ); 3646 } )( arguments ); 3647 3648 if ( memory && !firing ) { 3649 fire(); 3650 } 3651 } 3652 return this; 3653 }, 3654 3655 // Remove a callback from the list 3656 remove: function() { 3657 jQuery.each( arguments, function( _, arg ) { 3658 var index; 3659 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3660 list.splice( index, 1 ); 3661 3662 // Handle firing indexes 3663 if ( index <= firingIndex ) { 3664 firingIndex--; 3665 } 3666 } 3667 } ); 3668 return this; 3669 }, 3670 3671 // Check if a given callback is in the list. 3672 // If no argument is given, return whether or not list has callbacks attached. 3673 has: function( fn ) { 3674 return fn ? 3675 jQuery.inArray( fn, list ) > -1 : 3676 list.length > 0; 3677 }, 3678 3679 // Remove all callbacks from the list 3680 empty: function() { 3681 if ( list ) { 3682 list = []; 3683 } 3684 return this; 3685 }, 3686 3687 // Disable .fire and .add 3688 // Abort any current/pending executions 3689 // Clear all callbacks and values 3690 disable: function() { 3691 locked = queue = []; 3692 list = memory = ""; 3693 return this; 3694 }, 3695 disabled: function() { 3696 return !list; 3697 }, 3698 3699 // Disable .fire 3700 // Also disable .add unless we have memory (since it would have no effect) 3701 // Abort any pending executions 3702 lock: function() { 3703 locked = queue = []; 3704 if ( !memory && !firing ) { 3705 list = memory = ""; 3706 } 3707 return this; 3708 }, 3709 locked: function() { 3710 return !!locked; 3711 }, 3712 3713 // Call all callbacks with the given context and arguments 3714 fireWith: function( context, args ) { 3715 if ( !locked ) { 3716 args = args || []; 3717 args = [ context, args.slice ? args.slice() : args ]; 3718 queue.push( args ); 3719 if ( !firing ) { 3720 fire(); 3721 } 3722 } 3723 return this; 3724 }, 3725 3726 // Call all the callbacks with the given arguments 3727 fire: function() { 3728 self.fireWith( this, arguments ); 3729 return this; 3730 }, 3731 3732 // To know if the callbacks have already been called at least once 3733 fired: function() { 3734 return !!fired; 3735 } 3736 }; 3737 3738 return self; 3739}; 3740 3741 3742function Identity( v ) { 3743 return v; 3744} 3745function Thrower( ex ) { 3746 throw ex; 3747} 3748 3749function adoptValue( value, resolve, reject, noValue ) { 3750 var method; 3751 3752 try { 3753 3754 // Check for promise aspect first to privilege synchronous behavior 3755 if ( value && isFunction( ( method = value.promise ) ) ) { 3756 method.call( value ).done( resolve ).fail( reject ); 3757 3758 // Other thenables 3759 } else if ( value && isFunction( ( method = value.then ) ) ) { 3760 method.call( value, resolve, reject ); 3761 3762 // Other non-thenables 3763 } else { 3764 3765 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 3766 // * false: [ value ].slice( 0 ) => resolve( value ) 3767 // * true: [ value ].slice( 1 ) => resolve() 3768 resolve.apply( undefined, [ value ].slice( noValue ) ); 3769 } 3770 3771 // For Promises/A+, convert exceptions into rejections 3772 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 3773 // Deferred#then to conditionally suppress rejection. 3774 } catch ( value ) { 3775 3776 // Support: Android 4.0 only 3777 // Strict mode functions invoked without .call/.apply get global-object context 3778 reject.apply( undefined, [ value ] ); 3779 } 3780} 3781 3782jQuery.extend( { 3783 3784 Deferred: function( func ) { 3785 var tuples = [ 3786 3787 // action, add listener, callbacks, 3788 // ... .then handlers, argument index, [final state] 3789 [ "notify", "progress", jQuery.Callbacks( "memory" ), 3790 jQuery.Callbacks( "memory" ), 2 ], 3791 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 3792 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 3793 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 3794 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 3795 ], 3796 state = "pending", 3797 promise = { 3798 state: function() { 3799 return state; 3800 }, 3801 always: function() { 3802 deferred.done( arguments ).fail( arguments ); 3803 return this; 3804 }, 3805 "catch": function( fn ) { 3806 return promise.then( null, fn ); 3807 }, 3808 3809 // Keep pipe for back-compat 3810 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 3811 var fns = arguments; 3812 3813 return jQuery.Deferred( function( newDefer ) { 3814 jQuery.each( tuples, function( _i, tuple ) { 3815 3816 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 3817 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 3818 3819 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 3820 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 3821 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 3822 deferred[ tuple[ 1 ] ]( function() { 3823 var returned = fn && fn.apply( this, arguments ); 3824 if ( returned && isFunction( returned.promise ) ) { 3825 returned.promise() 3826 .progress( newDefer.notify ) 3827 .done( newDefer.resolve ) 3828 .fail( newDefer.reject ); 3829 } else { 3830 newDefer[ tuple[ 0 ] + "With" ]( 3831 this, 3832 fn ? [ returned ] : arguments 3833 ); 3834 } 3835 } ); 3836 } ); 3837 fns = null; 3838 } ).promise(); 3839 }, 3840 then: function( onFulfilled, onRejected, onProgress ) { 3841 var maxDepth = 0; 3842 function resolve( depth, deferred, handler, special ) { 3843 return function() { 3844 var that = this, 3845 args = arguments, 3846 mightThrow = function() { 3847 var returned, then; 3848 3849 // Support: Promises/A+ section 2.3.3.3.3 3850 // https://promisesaplus.com/#point-59 3851 // Ignore double-resolution attempts 3852 if ( depth < maxDepth ) { 3853 return; 3854 } 3855 3856 returned = handler.apply( that, args ); 3857 3858 // Support: Promises/A+ section 2.3.1 3859 // https://promisesaplus.com/#point-48 3860 if ( returned === deferred.promise() ) { 3861 throw new TypeError( "Thenable self-resolution" ); 3862 } 3863 3864 // Support: Promises/A+ sections 2.3.3.1, 3.5 3865 // https://promisesaplus.com/#point-54 3866 // https://promisesaplus.com/#point-75 3867 // Retrieve `then` only once 3868 then = returned && 3869 3870 // Support: Promises/A+ section 2.3.4 3871 // https://promisesaplus.com/#point-64 3872 // Only check objects and functions for thenability 3873 ( typeof returned === "object" || 3874 typeof returned === "function" ) && 3875 returned.then; 3876 3877 // Handle a returned thenable 3878 if ( isFunction( then ) ) { 3879 3880 // Special processors (notify) just wait for resolution 3881 if ( special ) { 3882 then.call( 3883 returned, 3884 resolve( maxDepth, deferred, Identity, special ), 3885 resolve( maxDepth, deferred, Thrower, special ) 3886 ); 3887 3888 // Normal processors (resolve) also hook into progress 3889 } else { 3890 3891 // ...and disregard older resolution values 3892 maxDepth++; 3893 3894 then.call( 3895 returned, 3896 resolve( maxDepth, deferred, Identity, special ), 3897 resolve( maxDepth, deferred, Thrower, special ), 3898 resolve( maxDepth, deferred, Identity, 3899 deferred.notifyWith ) 3900 ); 3901 } 3902 3903 // Handle all other returned values 3904 } else { 3905 3906 // Only substitute handlers pass on context 3907 // and multiple values (non-spec behavior) 3908 if ( handler !== Identity ) { 3909 that = undefined; 3910 args = [ returned ]; 3911 } 3912 3913 // Process the value(s) 3914 // Default process is resolve 3915 ( special || deferred.resolveWith )( that, args ); 3916 } 3917 }, 3918 3919 // Only normal processors (resolve) catch and reject exceptions 3920 process = special ? 3921 mightThrow : 3922 function() { 3923 try { 3924 mightThrow(); 3925 } catch ( e ) { 3926 3927 if ( jQuery.Deferred.exceptionHook ) { 3928 jQuery.Deferred.exceptionHook( e, 3929 process.stackTrace ); 3930 } 3931 3932 // Support: Promises/A+ section 2.3.3.3.4.1 3933 // https://promisesaplus.com/#point-61 3934 // Ignore post-resolution exceptions 3935 if ( depth + 1 >= maxDepth ) { 3936 3937 // Only substitute handlers pass on context 3938 // and multiple values (non-spec behavior) 3939 if ( handler !== Thrower ) { 3940 that = undefined; 3941 args = [ e ]; 3942 } 3943 3944 deferred.rejectWith( that, args ); 3945 } 3946 } 3947 }; 3948 3949 // Support: Promises/A+ section 2.3.3.3.1 3950 // https://promisesaplus.com/#point-57 3951 // Re-resolve promises immediately to dodge false rejection from 3952 // subsequent errors 3953 if ( depth ) { 3954 process(); 3955 } else { 3956 3957 // Call an optional hook to record the stack, in case of exception 3958 // since it's otherwise lost when execution goes async 3959 if ( jQuery.Deferred.getStackHook ) { 3960 process.stackTrace = jQuery.Deferred.getStackHook(); 3961 } 3962 window.setTimeout( process ); 3963 } 3964 }; 3965 } 3966 3967 return jQuery.Deferred( function( newDefer ) { 3968 3969 // progress_handlers.add( ... ) 3970 tuples[ 0 ][ 3 ].add( 3971 resolve( 3972 0, 3973 newDefer, 3974 isFunction( onProgress ) ? 3975 onProgress : 3976 Identity, 3977 newDefer.notifyWith 3978 ) 3979 ); 3980 3981 // fulfilled_handlers.add( ... ) 3982 tuples[ 1 ][ 3 ].add( 3983 resolve( 3984 0, 3985 newDefer, 3986 isFunction( onFulfilled ) ? 3987 onFulfilled : 3988 Identity 3989 ) 3990 ); 3991 3992 // rejected_handlers.add( ... ) 3993 tuples[ 2 ][ 3 ].add( 3994 resolve( 3995 0, 3996 newDefer, 3997 isFunction( onRejected ) ? 3998 onRejected : 3999 Thrower 4000 ) 4001 ); 4002 } ).promise(); 4003 }, 4004 4005 // Get a promise for this deferred 4006 // If obj is provided, the promise aspect is added to the object 4007 promise: function( obj ) { 4008 return obj != null ? jQuery.extend( obj, promise ) : promise; 4009 } 4010 }, 4011 deferred = {}; 4012 4013 // Add list-specific methods 4014 jQuery.each( tuples, function( i, tuple ) { 4015 var list = tuple[ 2 ], 4016 stateString = tuple[ 5 ]; 4017 4018 // promise.progress = list.add 4019 // promise.done = list.add 4020 // promise.fail = list.add 4021 promise[ tuple[ 1 ] ] = list.add; 4022 4023 // Handle state 4024 if ( stateString ) { 4025 list.add( 4026 function() { 4027 4028 // state = "resolved" (i.e., fulfilled) 4029 // state = "rejected" 4030 state = stateString; 4031 }, 4032 4033 // rejected_callbacks.disable 4034 // fulfilled_callbacks.disable 4035 tuples[ 3 - i ][ 2 ].disable, 4036 4037 // rejected_handlers.disable 4038 // fulfilled_handlers.disable 4039 tuples[ 3 - i ][ 3 ].disable, 4040 4041 // progress_callbacks.lock 4042 tuples[ 0 ][ 2 ].lock, 4043 4044 // progress_handlers.lock 4045 tuples[ 0 ][ 3 ].lock 4046 ); 4047 } 4048 4049 // progress_handlers.fire 4050 // fulfilled_handlers.fire 4051 // rejected_handlers.fire 4052 list.add( tuple[ 3 ].fire ); 4053 4054 // deferred.notify = function() { deferred.notifyWith(...) } 4055 // deferred.resolve = function() { deferred.resolveWith(...) } 4056 // deferred.reject = function() { deferred.rejectWith(...) } 4057 deferred[ tuple[ 0 ] ] = function() { 4058 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 4059 return this; 4060 }; 4061 4062 // deferred.notifyWith = list.fireWith 4063 // deferred.resolveWith = list.fireWith 4064 // deferred.rejectWith = list.fireWith 4065 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 4066 } ); 4067 4068 // Make the deferred a promise 4069 promise.promise( deferred ); 4070 4071 // Call given func if any 4072 if ( func ) { 4073 func.call( deferred, deferred ); 4074 } 4075 4076 // All done! 4077 return deferred; 4078 }, 4079 4080 // Deferred helper 4081 when: function( singleValue ) { 4082 var 4083 4084 // count of uncompleted subordinates 4085 remaining = arguments.length, 4086 4087 // count of unprocessed arguments 4088 i = remaining, 4089 4090 // subordinate fulfillment data 4091 resolveContexts = Array( i ), 4092 resolveValues = slice.call( arguments ), 4093 4094 // the primary Deferred 4095 primary = jQuery.Deferred(), 4096 4097 // subordinate callback factory 4098 updateFunc = function( i ) { 4099 return function( value ) { 4100 resolveContexts[ i ] = this; 4101 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 4102 if ( !( --remaining ) ) { 4103 primary.resolveWith( resolveContexts, resolveValues ); 4104 } 4105 }; 4106 }; 4107 4108 // Single- and empty arguments are adopted like Promise.resolve 4109 if ( remaining <= 1 ) { 4110 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 4111 !remaining ); 4112 4113 // Use .then() to unwrap secondary thenables (cf. gh-3000) 4114 if ( primary.state() === "pending" || 4115 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 4116 4117 return primary.then(); 4118 } 4119 } 4120 4121 // Multiple arguments are aggregated like Promise.all array elements 4122 while ( i-- ) { 4123 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 4124 } 4125 4126 return primary.promise(); 4127 } 4128} ); 4129 4130 4131// These usually indicate a programmer mistake during development, 4132// warn about them ASAP rather than swallowing them by default. 4133var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 4134 4135jQuery.Deferred.exceptionHook = function( error, stack ) { 4136 4137 // Support: IE 8 - 9 only 4138 // Console exists when dev tools are open, which can happen at any time 4139 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 4140 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 4141 } 4142}; 4143 4144 4145 4146 4147jQuery.readyException = function( error ) { 4148 window.setTimeout( function() { 4149 throw error; 4150 } ); 4151}; 4152 4153 4154 4155 4156// The deferred used on DOM ready 4157var readyList = jQuery.Deferred(); 4158 4159jQuery.fn.ready = function( fn ) { 4160 4161 readyList 4162 .then( fn ) 4163 4164 // Wrap jQuery.readyException in a function so that the lookup 4165 // happens at the time of error handling instead of callback 4166 // registration. 4167 .catch( function( error ) { 4168 jQuery.readyException( error ); 4169 } ); 4170 4171 return this; 4172}; 4173 4174jQuery.extend( { 4175 4176 // Is the DOM ready to be used? Set to true once it occurs. 4177 isReady: false, 4178 4179 // A counter to track how many items to wait for before 4180 // the ready event fires. See #6781 4181 readyWait: 1, 4182 4183 // Handle when the DOM is ready 4184 ready: function( wait ) { 4185 4186 // Abort if there are pending holds or we're already ready 4187 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 4188 return; 4189 } 4190 4191 // Remember that the DOM is ready 4192 jQuery.isReady = true; 4193 4194 // If a normal DOM Ready event fired, decrement, and wait if need be 4195 if ( wait !== true && --jQuery.readyWait > 0 ) { 4196 return; 4197 } 4198 4199 // If there are functions bound, to execute 4200 readyList.resolveWith( document, [ jQuery ] ); 4201 } 4202} ); 4203 4204jQuery.ready.then = readyList.then; 4205 4206// The ready event handler and self cleanup method 4207function completed() { 4208 document.removeEventListener( "DOMContentLoaded", completed ); 4209 window.removeEventListener( "load", completed ); 4210 jQuery.ready(); 4211} 4212 4213// Catch cases where $(document).ready() is called 4214// after the browser event has already occurred. 4215// Support: IE <=9 - 10 only 4216// Older IE sometimes signals "interactive" too soon 4217if ( document.readyState === "complete" || 4218 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 4219 4220 // Handle it asynchronously to allow scripts the opportunity to delay ready 4221 window.setTimeout( jQuery.ready ); 4222 4223} else { 4224 4225 // Use the handy event callback 4226 document.addEventListener( "DOMContentLoaded", completed ); 4227 4228 // A fallback to window.onload, that will always work 4229 window.addEventListener( "load", completed ); 4230} 4231 4232 4233 4234 4235// Multifunctional method to get and set values of a collection 4236// The value/s can optionally be executed if it's a function 4237var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 4238 var i = 0, 4239 len = elems.length, 4240 bulk = key == null; 4241 4242 // Sets many values 4243 if ( toType( key ) === "object" ) { 4244 chainable = true; 4245 for ( i in key ) { 4246 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 4247 } 4248 4249 // Sets one value 4250 } else if ( value !== undefined ) { 4251 chainable = true; 4252 4253 if ( !isFunction( value ) ) { 4254 raw = true; 4255 } 4256 4257 if ( bulk ) { 4258 4259 // Bulk operations run against the entire set 4260 if ( raw ) { 4261 fn.call( elems, value ); 4262 fn = null; 4263 4264 // ...except when executing function values 4265 } else { 4266 bulk = fn; 4267 fn = function( elem, _key, value ) { 4268 return bulk.call( jQuery( elem ), value ); 4269 }; 4270 } 4271 } 4272 4273 if ( fn ) { 4274 for ( ; i < len; i++ ) { 4275 fn( 4276 elems[ i ], key, raw ? 4277 value : 4278 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 4279 ); 4280 } 4281 } 4282 } 4283 4284 if ( chainable ) { 4285 return elems; 4286 } 4287 4288 // Gets 4289 if ( bulk ) { 4290 return fn.call( elems ); 4291 } 4292 4293 return len ? fn( elems[ 0 ], key ) : emptyGet; 4294}; 4295 4296 4297// Matches dashed string for camelizing 4298var rmsPrefix = /^-ms-/, 4299 rdashAlpha = /-([a-z])/g; 4300 4301// Used by camelCase as callback to replace() 4302function fcamelCase( _all, letter ) { 4303 return letter.toUpperCase(); 4304} 4305 4306// Convert dashed to camelCase; used by the css and data modules 4307// Support: IE <=9 - 11, Edge 12 - 15 4308// Microsoft forgot to hump their vendor prefix (#9572) 4309function camelCase( string ) { 4310 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 4311} 4312var acceptData = function( owner ) { 4313 4314 // Accepts only: 4315 // - Node 4316 // - Node.ELEMENT_NODE 4317 // - Node.DOCUMENT_NODE 4318 // - Object 4319 // - Any 4320 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 4321}; 4322 4323 4324 4325 4326function Data() { 4327 this.expando = jQuery.expando + Data.uid++; 4328} 4329 4330Data.uid = 1; 4331 4332Data.prototype = { 4333 4334 cache: function( owner ) { 4335 4336 // Check if the owner object already has a cache 4337 var value = owner[ this.expando ]; 4338 4339 // If not, create one 4340 if ( !value ) { 4341 value = {}; 4342 4343 // We can accept data for non-element nodes in modern browsers, 4344 // but we should not, see #8335. 4345 // Always return an empty object. 4346 if ( acceptData( owner ) ) { 4347 4348 // If it is a node unlikely to be stringify-ed or looped over 4349 // use plain assignment 4350 if ( owner.nodeType ) { 4351 owner[ this.expando ] = value; 4352 4353 // Otherwise secure it in a non-enumerable property 4354 // configurable must be true to allow the property to be 4355 // deleted when data is removed 4356 } else { 4357 Object.defineProperty( owner, this.expando, { 4358 value: value, 4359 configurable: true 4360 } ); 4361 } 4362 } 4363 } 4364 4365 return value; 4366 }, 4367 set: function( owner, data, value ) { 4368 var prop, 4369 cache = this.cache( owner ); 4370 4371 // Handle: [ owner, key, value ] args 4372 // Always use camelCase key (gh-2257) 4373 if ( typeof data === "string" ) { 4374 cache[ camelCase( data ) ] = value; 4375 4376 // Handle: [ owner, { properties } ] args 4377 } else { 4378 4379 // Copy the properties one-by-one to the cache object 4380 for ( prop in data ) { 4381 cache[ camelCase( prop ) ] = data[ prop ]; 4382 } 4383 } 4384 return cache; 4385 }, 4386 get: function( owner, key ) { 4387 return key === undefined ? 4388 this.cache( owner ) : 4389 4390 // Always use camelCase key (gh-2257) 4391 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 4392 }, 4393 access: function( owner, key, value ) { 4394 4395 // In cases where either: 4396 // 4397 // 1. No key was specified 4398 // 2. A string key was specified, but no value provided 4399 // 4400 // Take the "read" path and allow the get method to determine 4401 // which value to return, respectively either: 4402 // 4403 // 1. The entire cache object 4404 // 2. The data stored at the key 4405 // 4406 if ( key === undefined || 4407 ( ( key && typeof key === "string" ) && value === undefined ) ) { 4408 4409 return this.get( owner, key ); 4410 } 4411 4412 // When the key is not a string, or both a key and value 4413 // are specified, set or extend (existing objects) with either: 4414 // 4415 // 1. An object of properties 4416 // 2. A key and value 4417 // 4418 this.set( owner, key, value ); 4419 4420 // Since the "set" path can have two possible entry points 4421 // return the expected data based on which path was taken[*] 4422 return value !== undefined ? value : key; 4423 }, 4424 remove: function( owner, key ) { 4425 var i, 4426 cache = owner[ this.expando ]; 4427 4428 if ( cache === undefined ) { 4429 return; 4430 } 4431 4432 if ( key !== undefined ) { 4433 4434 // Support array or space separated string of keys 4435 if ( Array.isArray( key ) ) { 4436 4437 // If key is an array of keys... 4438 // We always set camelCase keys, so remove that. 4439 key = key.map( camelCase ); 4440 } else { 4441 key = camelCase( key ); 4442 4443 // If a key with the spaces exists, use it. 4444 // Otherwise, create an array by matching non-whitespace 4445 key = key in cache ? 4446 [ key ] : 4447 ( key.match( rnothtmlwhite ) || [] ); 4448 } 4449 4450 i = key.length; 4451 4452 while ( i-- ) { 4453 delete cache[ key[ i ] ]; 4454 } 4455 } 4456 4457 // Remove the expando if there's no more data 4458 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 4459 4460 // Support: Chrome <=35 - 45 4461 // Webkit & Blink performance suffers when deleting properties 4462 // from DOM nodes, so set to undefined instead 4463 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 4464 if ( owner.nodeType ) { 4465 owner[ this.expando ] = undefined; 4466 } else { 4467 delete owner[ this.expando ]; 4468 } 4469 } 4470 }, 4471 hasData: function( owner ) { 4472 var cache = owner[ this.expando ]; 4473 return cache !== undefined && !jQuery.isEmptyObject( cache ); 4474 } 4475}; 4476var dataPriv = new Data(); 4477 4478var dataUser = new Data(); 4479 4480 4481 4482// Implementation Summary 4483// 4484// 1. Enforce API surface and semantic compatibility with 1.9.x branch 4485// 2. Improve the module's maintainability by reducing the storage 4486// paths to a single mechanism. 4487// 3. Use the same single mechanism to support "private" and "user" data. 4488// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 4489// 5. Avoid exposing implementation details on user objects (eg. expando properties) 4490// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 4491 4492var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 4493 rmultiDash = /[A-Z]/g; 4494 4495function getData( data ) { 4496 if ( data === "true" ) { 4497 return true; 4498 } 4499 4500 if ( data === "false" ) { 4501 return false; 4502 } 4503 4504 if ( data === "null" ) { 4505 return null; 4506 } 4507 4508 // Only convert to a number if it doesn't change the string 4509 if ( data === +data + "" ) { 4510 return +data; 4511 } 4512 4513 if ( rbrace.test( data ) ) { 4514 return JSON.parse( data ); 4515 } 4516 4517 return data; 4518} 4519 4520function dataAttr( elem, key, data ) { 4521 var name; 4522 4523 // If nothing was found internally, try to fetch any 4524 // data from the HTML5 data-* attribute 4525 if ( data === undefined && elem.nodeType === 1 ) { 4526 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 4527 data = elem.getAttribute( name ); 4528 4529 if ( typeof data === "string" ) { 4530 try { 4531 data = getData( data ); 4532 } catch ( e ) {} 4533 4534 // Make sure we set the data so it isn't changed later 4535 dataUser.set( elem, key, data ); 4536 } else { 4537 data = undefined; 4538 } 4539 } 4540 return data; 4541} 4542 4543jQuery.extend( { 4544 hasData: function( elem ) { 4545 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 4546 }, 4547 4548 data: function( elem, name, data ) { 4549 return dataUser.access( elem, name, data ); 4550 }, 4551 4552 removeData: function( elem, name ) { 4553 dataUser.remove( elem, name ); 4554 }, 4555 4556 // TODO: Now that all calls to _data and _removeData have been replaced 4557 // with direct calls to dataPriv methods, these can be deprecated. 4558 _data: function( elem, name, data ) { 4559 return dataPriv.access( elem, name, data ); 4560 }, 4561 4562 _removeData: function( elem, name ) { 4563 dataPriv.remove( elem, name ); 4564 } 4565} ); 4566 4567jQuery.fn.extend( { 4568 data: function( key, value ) { 4569 var i, name, data, 4570 elem = this[ 0 ], 4571 attrs = elem && elem.attributes; 4572 4573 // Gets all values 4574 if ( key === undefined ) { 4575 if ( this.length ) { 4576 data = dataUser.get( elem ); 4577 4578 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 4579 i = attrs.length; 4580 while ( i-- ) { 4581 4582 // Support: IE 11 only 4583 // The attrs elements can be null (#14894) 4584 if ( attrs[ i ] ) { 4585 name = attrs[ i ].name; 4586 if ( name.indexOf( "data-" ) === 0 ) { 4587 name = camelCase( name.slice( 5 ) ); 4588 dataAttr( elem, name, data[ name ] ); 4589 } 4590 } 4591 } 4592 dataPriv.set( elem, "hasDataAttrs", true ); 4593 } 4594 } 4595 4596 return data; 4597 } 4598 4599 // Sets multiple values 4600 if ( typeof key === "object" ) { 4601 return this.each( function() { 4602 dataUser.set( this, key ); 4603 } ); 4604 } 4605 4606 return access( this, function( value ) { 4607 var data; 4608 4609 // The calling jQuery object (element matches) is not empty 4610 // (and therefore has an element appears at this[ 0 ]) and the 4611 // `value` parameter was not undefined. An empty jQuery object 4612 // will result in `undefined` for elem = this[ 0 ] which will 4613 // throw an exception if an attempt to read a data cache is made. 4614 if ( elem && value === undefined ) { 4615 4616 // Attempt to get data from the cache 4617 // The key will always be camelCased in Data 4618 data = dataUser.get( elem, key ); 4619 if ( data !== undefined ) { 4620 return data; 4621 } 4622 4623 // Attempt to "discover" the data in 4624 // HTML5 custom data-* attrs 4625 data = dataAttr( elem, key ); 4626 if ( data !== undefined ) { 4627 return data; 4628 } 4629 4630 // We tried really hard, but the data doesn't exist. 4631 return; 4632 } 4633 4634 // Set the data... 4635 this.each( function() { 4636 4637 // We always store the camelCased key 4638 dataUser.set( this, key, value ); 4639 } ); 4640 }, null, value, arguments.length > 1, null, true ); 4641 }, 4642 4643 removeData: function( key ) { 4644 return this.each( function() { 4645 dataUser.remove( this, key ); 4646 } ); 4647 } 4648} ); 4649 4650 4651jQuery.extend( { 4652 queue: function( elem, type, data ) { 4653 var queue; 4654 4655 if ( elem ) { 4656 type = ( type || "fx" ) + "queue"; 4657 queue = dataPriv.get( elem, type ); 4658 4659 // Speed up dequeue by getting out quickly if this is just a lookup 4660 if ( data ) { 4661 if ( !queue || Array.isArray( data ) ) { 4662 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 4663 } else { 4664 queue.push( data ); 4665 } 4666 } 4667 return queue || []; 4668 } 4669 }, 4670 4671 dequeue: function( elem, type ) { 4672 type = type || "fx"; 4673 4674 var queue = jQuery.queue( elem, type ), 4675 startLength = queue.length, 4676 fn = queue.shift(), 4677 hooks = jQuery._queueHooks( elem, type ), 4678 next = function() { 4679 jQuery.dequeue( elem, type ); 4680 }; 4681 4682 // If the fx queue is dequeued, always remove the progress sentinel 4683 if ( fn === "inprogress" ) { 4684 fn = queue.shift(); 4685 startLength--; 4686 } 4687 4688 if ( fn ) { 4689 4690 // Add a progress sentinel to prevent the fx queue from being 4691 // automatically dequeued 4692 if ( type === "fx" ) { 4693 queue.unshift( "inprogress" ); 4694 } 4695 4696 // Clear up the last queue stop function 4697 delete hooks.stop; 4698 fn.call( elem, next, hooks ); 4699 } 4700 4701 if ( !startLength && hooks ) { 4702 hooks.empty.fire(); 4703 } 4704 }, 4705 4706 // Not public - generate a queueHooks object, or return the current one 4707 _queueHooks: function( elem, type ) { 4708 var key = type + "queueHooks"; 4709 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 4710 empty: jQuery.Callbacks( "once memory" ).add( function() { 4711 dataPriv.remove( elem, [ type + "queue", key ] ); 4712 } ) 4713 } ); 4714 } 4715} ); 4716 4717jQuery.fn.extend( { 4718 queue: function( type, data ) { 4719 var setter = 2; 4720 4721 if ( typeof type !== "string" ) { 4722 data = type; 4723 type = "fx"; 4724 setter--; 4725 } 4726 4727 if ( arguments.length < setter ) { 4728 return jQuery.queue( this[ 0 ], type ); 4729 } 4730 4731 return data === undefined ? 4732 this : 4733 this.each( function() { 4734 var queue = jQuery.queue( this, type, data ); 4735 4736 // Ensure a hooks for this queue 4737 jQuery._queueHooks( this, type ); 4738 4739 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 4740 jQuery.dequeue( this, type ); 4741 } 4742 } ); 4743 }, 4744 dequeue: function( type ) { 4745 return this.each( function() { 4746 jQuery.dequeue( this, type ); 4747 } ); 4748 }, 4749 clearQueue: function( type ) { 4750 return this.queue( type || "fx", [] ); 4751 }, 4752 4753 // Get a promise resolved when queues of a certain type 4754 // are emptied (fx is the type by default) 4755 promise: function( type, obj ) { 4756 var tmp, 4757 count = 1, 4758 defer = jQuery.Deferred(), 4759 elements = this, 4760 i = this.length, 4761 resolve = function() { 4762 if ( !( --count ) ) { 4763 defer.resolveWith( elements, [ elements ] ); 4764 } 4765 }; 4766 4767 if ( typeof type !== "string" ) { 4768 obj = type; 4769 type = undefined; 4770 } 4771 type = type || "fx"; 4772 4773 while ( i-- ) { 4774 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 4775 if ( tmp && tmp.empty ) { 4776 count++; 4777 tmp.empty.add( resolve ); 4778 } 4779 } 4780 resolve(); 4781 return defer.promise( obj ); 4782 } 4783} ); 4784var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 4785 4786var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 4787 4788 4789var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4790 4791var documentElement = document.documentElement; 4792 4793 4794 4795 var isAttached = function( elem ) { 4796 return jQuery.contains( elem.ownerDocument, elem ); 4797 }, 4798 composed = { composed: true }; 4799 4800 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 4801 // Check attachment across shadow DOM boundaries when possible (gh-3504) 4802 // Support: iOS 10.0-10.2 only 4803 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 4804 // leading to errors. We need to check for `getRootNode`. 4805 if ( documentElement.getRootNode ) { 4806 isAttached = function( elem ) { 4807 return jQuery.contains( elem.ownerDocument, elem ) || 4808 elem.getRootNode( composed ) === elem.ownerDocument; 4809 }; 4810 } 4811var isHiddenWithinTree = function( elem, el ) { 4812 4813 // isHiddenWithinTree might be called from jQuery#filter function; 4814 // in that case, element will be second argument 4815 elem = el || elem; 4816 4817 // Inline style trumps all 4818 return elem.style.display === "none" || 4819 elem.style.display === "" && 4820 4821 // Otherwise, check computed style 4822 // Support: Firefox <=43 - 45 4823 // Disconnected elements can have computed display: none, so first confirm that elem is 4824 // in the document. 4825 isAttached( elem ) && 4826 4827 jQuery.css( elem, "display" ) === "none"; 4828 }; 4829 4830 4831 4832function adjustCSS( elem, prop, valueParts, tween ) { 4833 var adjusted, scale, 4834 maxIterations = 20, 4835 currentValue = tween ? 4836 function() { 4837 return tween.cur(); 4838 } : 4839 function() { 4840 return jQuery.css( elem, prop, "" ); 4841 }, 4842 initial = currentValue(), 4843 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 4844 4845 // Starting value computation is required for potential unit mismatches 4846 initialInUnit = elem.nodeType && 4847 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 4848 rcssNum.exec( jQuery.css( elem, prop ) ); 4849 4850 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 4851 4852 // Support: Firefox <=54 4853 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 4854 initial = initial / 2; 4855 4856 // Trust units reported by jQuery.css 4857 unit = unit || initialInUnit[ 3 ]; 4858 4859 // Iteratively approximate from a nonzero starting point 4860 initialInUnit = +initial || 1; 4861 4862 while ( maxIterations-- ) { 4863 4864 // Evaluate and update our best guess (doubling guesses that zero out). 4865 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 4866 jQuery.style( elem, prop, initialInUnit + unit ); 4867 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 4868 maxIterations = 0; 4869 } 4870 initialInUnit = initialInUnit / scale; 4871 4872 } 4873 4874 initialInUnit = initialInUnit * 2; 4875 jQuery.style( elem, prop, initialInUnit + unit ); 4876 4877 // Make sure we update the tween properties later on 4878 valueParts = valueParts || []; 4879 } 4880 4881 if ( valueParts ) { 4882 initialInUnit = +initialInUnit || +initial || 0; 4883 4884 // Apply relative offset (+=/-=) if specified 4885 adjusted = valueParts[ 1 ] ? 4886 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 4887 +valueParts[ 2 ]; 4888 if ( tween ) { 4889 tween.unit = unit; 4890 tween.start = initialInUnit; 4891 tween.end = adjusted; 4892 } 4893 } 4894 return adjusted; 4895} 4896 4897 4898var defaultDisplayMap = {}; 4899 4900function getDefaultDisplay( elem ) { 4901 var temp, 4902 doc = elem.ownerDocument, 4903 nodeName = elem.nodeName, 4904 display = defaultDisplayMap[ nodeName ]; 4905 4906 if ( display ) { 4907 return display; 4908 } 4909 4910 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 4911 display = jQuery.css( temp, "display" ); 4912 4913 temp.parentNode.removeChild( temp ); 4914 4915 if ( display === "none" ) { 4916 display = "block"; 4917 } 4918 defaultDisplayMap[ nodeName ] = display; 4919 4920 return display; 4921} 4922 4923function showHide( elements, show ) { 4924 var display, elem, 4925 values = [], 4926 index = 0, 4927 length = elements.length; 4928 4929 // Determine new display value for elements that need to change 4930 for ( ; index < length; index++ ) { 4931 elem = elements[ index ]; 4932 if ( !elem.style ) { 4933 continue; 4934 } 4935 4936 display = elem.style.display; 4937 if ( show ) { 4938 4939 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 4940 // check is required in this first loop unless we have a nonempty display value (either 4941 // inline or about-to-be-restored) 4942 if ( display === "none" ) { 4943 values[ index ] = dataPriv.get( elem, "display" ) || null; 4944 if ( !values[ index ] ) { 4945 elem.style.display = ""; 4946 } 4947 } 4948 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 4949 values[ index ] = getDefaultDisplay( elem ); 4950 } 4951 } else { 4952 if ( display !== "none" ) { 4953 values[ index ] = "none"; 4954 4955 // Remember what we're overwriting 4956 dataPriv.set( elem, "display", display ); 4957 } 4958 } 4959 } 4960 4961 // Set the display of the elements in a second loop to avoid constant reflow 4962 for ( index = 0; index < length; index++ ) { 4963 if ( values[ index ] != null ) { 4964 elements[ index ].style.display = values[ index ]; 4965 } 4966 } 4967 4968 return elements; 4969} 4970 4971jQuery.fn.extend( { 4972 show: function() { 4973 return showHide( this, true ); 4974 }, 4975 hide: function() { 4976 return showHide( this ); 4977 }, 4978 toggle: function( state ) { 4979 if ( typeof state === "boolean" ) { 4980 return state ? this.show() : this.hide(); 4981 } 4982 4983 return this.each( function() { 4984 if ( isHiddenWithinTree( this ) ) { 4985 jQuery( this ).show(); 4986 } else { 4987 jQuery( this ).hide(); 4988 } 4989 } ); 4990 } 4991} ); 4992var rcheckableType = ( /^(?:checkbox|radio)$/i ); 4993 4994var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 4995 4996var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 4997 4998 4999 5000( function() { 5001 var fragment = document.createDocumentFragment(), 5002 div = fragment.appendChild( document.createElement( "div" ) ), 5003 input = document.createElement( "input" ); 5004 5005 // Support: Android 4.0 - 4.3 only 5006 // Check state lost if the name is set (#11217) 5007 // Support: Windows Web Apps (WWA) 5008 // `name` and `type` must use .setAttribute for WWA (#14901) 5009 input.setAttribute( "type", "radio" ); 5010 input.setAttribute( "checked", "checked" ); 5011 input.setAttribute( "name", "t" ); 5012 5013 div.appendChild( input ); 5014 5015 // Support: Android <=4.1 only 5016 // Older WebKit doesn't clone checked state correctly in fragments 5017 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 5018 5019 // Support: IE <=11 only 5020 // Make sure textarea (and checkbox) defaultValue is properly cloned 5021 div.innerHTML = "<textarea>x</textarea>"; 5022 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 5023 5024 // Support: IE <=9 only 5025 // IE <=9 replaces <option> tags with their contents when inserted outside of 5026 // the select element. 5027 div.innerHTML = "<option></option>"; 5028 support.option = !!div.lastChild; 5029} )(); 5030 5031 5032// We have to close these tags to support XHTML (#13200) 5033var wrapMap = { 5034 5035 // XHTML parsers do not magically insert elements in the 5036 // same way that tag soup parsers do. So we cannot shorten 5037 // this by omitting <tbody> or other required elements. 5038 thead: [ 1, "<table>", "</table>" ], 5039 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 5040 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 5041 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 5042 5043 _default: [ 0, "", "" ] 5044}; 5045 5046wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 5047wrapMap.th = wrapMap.td; 5048 5049// Support: IE <=9 only 5050if ( !support.option ) { 5051 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 5052} 5053 5054 5055function getAll( context, tag ) { 5056 5057 // Support: IE <=9 - 11 only 5058 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 5059 var ret; 5060 5061 if ( typeof context.getElementsByTagName !== "undefined" ) { 5062 ret = context.getElementsByTagName( tag || "*" ); 5063 5064 } else if ( typeof context.querySelectorAll !== "undefined" ) { 5065 ret = context.querySelectorAll( tag || "*" ); 5066 5067 } else { 5068 ret = []; 5069 } 5070 5071 if ( tag === undefined || tag && nodeName( context, tag ) ) { 5072 return jQuery.merge( [ context ], ret ); 5073 } 5074 5075 return ret; 5076} 5077 5078 5079// Mark scripts as having already been evaluated 5080function setGlobalEval( elems, refElements ) { 5081 var i = 0, 5082 l = elems.length; 5083 5084 for ( ; i < l; i++ ) { 5085 dataPriv.set( 5086 elems[ i ], 5087 "globalEval", 5088 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 5089 ); 5090 } 5091} 5092 5093 5094var rhtml = /<|&#?\w+;/; 5095 5096function buildFragment( elems, context, scripts, selection, ignored ) { 5097 var elem, tmp, tag, wrap, attached, j, 5098 fragment = context.createDocumentFragment(), 5099 nodes = [], 5100 i = 0, 5101 l = elems.length; 5102 5103 for ( ; i < l; i++ ) { 5104 elem = elems[ i ]; 5105 5106 if ( elem || elem === 0 ) { 5107 5108 // Add nodes directly 5109 if ( toType( elem ) === "object" ) { 5110 5111 // Support: Android <=4.0 only, PhantomJS 1 only 5112 // push.apply(_, arraylike) throws on ancient WebKit 5113 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 5114 5115 // Convert non-html into a text node 5116 } else if ( !rhtml.test( elem ) ) { 5117 nodes.push( context.createTextNode( elem ) ); 5118 5119 // Convert html into DOM nodes 5120 } else { 5121 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 5122 5123 // Deserialize a standard representation 5124 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 5125 wrap = wrapMap[ tag ] || wrapMap._default; 5126 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 5127 5128 // Descend through wrappers to the right content 5129 j = wrap[ 0 ]; 5130 while ( j-- ) { 5131 tmp = tmp.lastChild; 5132 } 5133 5134 // Support: Android <=4.0 only, PhantomJS 1 only 5135 // push.apply(_, arraylike) throws on ancient WebKit 5136 jQuery.merge( nodes, tmp.childNodes ); 5137 5138 // Remember the top-level container 5139 tmp = fragment.firstChild; 5140 5141 // Ensure the created nodes are orphaned (#12392) 5142 tmp.textContent = ""; 5143 } 5144 } 5145 } 5146 5147 // Remove wrapper from fragment 5148 fragment.textContent = ""; 5149 5150 i = 0; 5151 while ( ( elem = nodes[ i++ ] ) ) { 5152 5153 // Skip elements already in the context collection (trac-4087) 5154 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 5155 if ( ignored ) { 5156 ignored.push( elem ); 5157 } 5158 continue; 5159 } 5160 5161 attached = isAttached( elem ); 5162 5163 // Append to fragment 5164 tmp = getAll( fragment.appendChild( elem ), "script" ); 5165 5166 // Preserve script evaluation history 5167 if ( attached ) { 5168 setGlobalEval( tmp ); 5169 } 5170 5171 // Capture executables 5172 if ( scripts ) { 5173 j = 0; 5174 while ( ( elem = tmp[ j++ ] ) ) { 5175 if ( rscriptType.test( elem.type || "" ) ) { 5176 scripts.push( elem ); 5177 } 5178 } 5179 } 5180 } 5181 5182 return fragment; 5183} 5184 5185 5186var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 5187 5188function returnTrue() { 5189 return true; 5190} 5191 5192function returnFalse() { 5193 return false; 5194} 5195 5196// Support: IE <=9 - 11+ 5197// focus() and blur() are asynchronous, except when they are no-op. 5198// So expect focus to be synchronous when the element is already active, 5199// and blur to be synchronous when the element is not already active. 5200// (focus and blur are always synchronous in other supported browsers, 5201// this just defines when we can count on it). 5202function expectSync( elem, type ) { 5203 return ( elem === safeActiveElement() ) === ( type === "focus" ); 5204} 5205 5206// Support: IE <=9 only 5207// Accessing document.activeElement can throw unexpectedly 5208// https://bugs.jquery.com/ticket/13393 5209function safeActiveElement() { 5210 try { 5211 return document.activeElement; 5212 } catch ( err ) { } 5213} 5214 5215function on( elem, types, selector, data, fn, one ) { 5216 var origFn, type; 5217 5218 // Types can be a map of types/handlers 5219 if ( typeof types === "object" ) { 5220 5221 // ( types-Object, selector, data ) 5222 if ( typeof selector !== "string" ) { 5223 5224 // ( types-Object, data ) 5225 data = data || selector; 5226 selector = undefined; 5227 } 5228 for ( type in types ) { 5229 on( elem, type, selector, data, types[ type ], one ); 5230 } 5231 return elem; 5232 } 5233 5234 if ( data == null && fn == null ) { 5235 5236 // ( types, fn ) 5237 fn = selector; 5238 data = selector = undefined; 5239 } else if ( fn == null ) { 5240 if ( typeof selector === "string" ) { 5241 5242 // ( types, selector, fn ) 5243 fn = data; 5244 data = undefined; 5245 } else { 5246 5247 // ( types, data, fn ) 5248 fn = data; 5249 data = selector; 5250 selector = undefined; 5251 } 5252 } 5253 if ( fn === false ) { 5254 fn = returnFalse; 5255 } else if ( !fn ) { 5256 return elem; 5257 } 5258 5259 if ( one === 1 ) { 5260 origFn = fn; 5261 fn = function( event ) { 5262 5263 // Can use an empty set, since event contains the info 5264 jQuery().off( event ); 5265 return origFn.apply( this, arguments ); 5266 }; 5267 5268 // Use same guid so caller can remove using origFn 5269 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 5270 } 5271 return elem.each( function() { 5272 jQuery.event.add( this, types, fn, data, selector ); 5273 } ); 5274} 5275 5276/* 5277 * Helper functions for managing events -- not part of the public interface. 5278 * Props to Dean Edwards' addEvent library for many of the ideas. 5279 */ 5280jQuery.event = { 5281 5282 global: {}, 5283 5284 add: function( elem, types, handler, data, selector ) { 5285 5286 var handleObjIn, eventHandle, tmp, 5287 events, t, handleObj, 5288 special, handlers, type, namespaces, origType, 5289 elemData = dataPriv.get( elem ); 5290 5291 // Only attach events to objects that accept data 5292 if ( !acceptData( elem ) ) { 5293 return; 5294 } 5295 5296 // Caller can pass in an object of custom data in lieu of the handler 5297 if ( handler.handler ) { 5298 handleObjIn = handler; 5299 handler = handleObjIn.handler; 5300 selector = handleObjIn.selector; 5301 } 5302 5303 // Ensure that invalid selectors throw exceptions at attach time 5304 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 5305 if ( selector ) { 5306 jQuery.find.matchesSelector( documentElement, selector ); 5307 } 5308 5309 // Make sure that the handler has a unique ID, used to find/remove it later 5310 if ( !handler.guid ) { 5311 handler.guid = jQuery.guid++; 5312 } 5313 5314 // Init the element's event structure and main handler, if this is the first 5315 if ( !( events = elemData.events ) ) { 5316 events = elemData.events = Object.create( null ); 5317 } 5318 if ( !( eventHandle = elemData.handle ) ) { 5319 eventHandle = elemData.handle = function( e ) { 5320 5321 // Discard the second event of a jQuery.event.trigger() and 5322 // when an event is called after a page has unloaded 5323 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 5324 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 5325 }; 5326 } 5327 5328 // Handle multiple events separated by a space 5329 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5330 t = types.length; 5331 while ( t-- ) { 5332 tmp = rtypenamespace.exec( types[ t ] ) || []; 5333 type = origType = tmp[ 1 ]; 5334 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5335 5336 // There *must* be a type, no attaching namespace-only handlers 5337 if ( !type ) { 5338 continue; 5339 } 5340 5341 // If event changes its type, use the special event handlers for the changed type 5342 special = jQuery.event.special[ type ] || {}; 5343 5344 // If selector defined, determine special event api type, otherwise given type 5345 type = ( selector ? special.delegateType : special.bindType ) || type; 5346 5347 // Update special based on newly reset type 5348 special = jQuery.event.special[ type ] || {}; 5349 5350 // handleObj is passed to all event handlers 5351 handleObj = jQuery.extend( { 5352 type: type, 5353 origType: origType, 5354 data: data, 5355 handler: handler, 5356 guid: handler.guid, 5357 selector: selector, 5358 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 5359 namespace: namespaces.join( "." ) 5360 }, handleObjIn ); 5361 5362 // Init the event handler queue if we're the first 5363 if ( !( handlers = events[ type ] ) ) { 5364 handlers = events[ type ] = []; 5365 handlers.delegateCount = 0; 5366 5367 // Only use addEventListener if the special events handler returns false 5368 if ( !special.setup || 5369 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 5370 5371 if ( elem.addEventListener ) { 5372 elem.addEventListener( type, eventHandle ); 5373 } 5374 } 5375 } 5376 5377 if ( special.add ) { 5378 special.add.call( elem, handleObj ); 5379 5380 if ( !handleObj.handler.guid ) { 5381 handleObj.handler.guid = handler.guid; 5382 } 5383 } 5384 5385 // Add to the element's handler list, delegates in front 5386 if ( selector ) { 5387 handlers.splice( handlers.delegateCount++, 0, handleObj ); 5388 } else { 5389 handlers.push( handleObj ); 5390 } 5391 5392 // Keep track of which events have ever been used, for event optimization 5393 jQuery.event.global[ type ] = true; 5394 } 5395 5396 }, 5397 5398 // Detach an event or set of events from an element 5399 remove: function( elem, types, handler, selector, mappedTypes ) { 5400 5401 var j, origCount, tmp, 5402 events, t, handleObj, 5403 special, handlers, type, namespaces, origType, 5404 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 5405 5406 if ( !elemData || !( events = elemData.events ) ) { 5407 return; 5408 } 5409 5410 // Once for each type.namespace in types; type may be omitted 5411 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5412 t = types.length; 5413 while ( t-- ) { 5414 tmp = rtypenamespace.exec( types[ t ] ) || []; 5415 type = origType = tmp[ 1 ]; 5416 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5417 5418 // Unbind all events (on this namespace, if provided) for the element 5419 if ( !type ) { 5420 for ( type in events ) { 5421 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 5422 } 5423 continue; 5424 } 5425 5426 special = jQuery.event.special[ type ] || {}; 5427 type = ( selector ? special.delegateType : special.bindType ) || type; 5428 handlers = events[ type ] || []; 5429 tmp = tmp[ 2 ] && 5430 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 5431 5432 // Remove matching events 5433 origCount = j = handlers.length; 5434 while ( j-- ) { 5435 handleObj = handlers[ j ]; 5436 5437 if ( ( mappedTypes || origType === handleObj.origType ) && 5438 ( !handler || handler.guid === handleObj.guid ) && 5439 ( !tmp || tmp.test( handleObj.namespace ) ) && 5440 ( !selector || selector === handleObj.selector || 5441 selector === "**" && handleObj.selector ) ) { 5442 handlers.splice( j, 1 ); 5443 5444 if ( handleObj.selector ) { 5445 handlers.delegateCount--; 5446 } 5447 if ( special.remove ) { 5448 special.remove.call( elem, handleObj ); 5449 } 5450 } 5451 } 5452 5453 // Remove generic event handler if we removed something and no more handlers exist 5454 // (avoids potential for endless recursion during removal of special event handlers) 5455 if ( origCount && !handlers.length ) { 5456 if ( !special.teardown || 5457 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 5458 5459 jQuery.removeEvent( elem, type, elemData.handle ); 5460 } 5461 5462 delete events[ type ]; 5463 } 5464 } 5465 5466 // Remove data and the expando if it's no longer used 5467 if ( jQuery.isEmptyObject( events ) ) { 5468 dataPriv.remove( elem, "handle events" ); 5469 } 5470 }, 5471 5472 dispatch: function( nativeEvent ) { 5473 5474 var i, j, ret, matched, handleObj, handlerQueue, 5475 args = new Array( arguments.length ), 5476 5477 // Make a writable jQuery.Event from the native event object 5478 event = jQuery.event.fix( nativeEvent ), 5479 5480 handlers = ( 5481 dataPriv.get( this, "events" ) || Object.create( null ) 5482 )[ event.type ] || [], 5483 special = jQuery.event.special[ event.type ] || {}; 5484 5485 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5486 args[ 0 ] = event; 5487 5488 for ( i = 1; i < arguments.length; i++ ) { 5489 args[ i ] = arguments[ i ]; 5490 } 5491 5492 event.delegateTarget = this; 5493 5494 // Call the preDispatch hook for the mapped type, and let it bail if desired 5495 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 5496 return; 5497 } 5498 5499 // Determine handlers 5500 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 5501 5502 // Run delegates first; they may want to stop propagation beneath us 5503 i = 0; 5504 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 5505 event.currentTarget = matched.elem; 5506 5507 j = 0; 5508 while ( ( handleObj = matched.handlers[ j++ ] ) && 5509 !event.isImmediatePropagationStopped() ) { 5510 5511 // If the event is namespaced, then each handler is only invoked if it is 5512 // specially universal or its namespaces are a superset of the event's. 5513 if ( !event.rnamespace || handleObj.namespace === false || 5514 event.rnamespace.test( handleObj.namespace ) ) { 5515 5516 event.handleObj = handleObj; 5517 event.data = handleObj.data; 5518 5519 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 5520 handleObj.handler ).apply( matched.elem, args ); 5521 5522 if ( ret !== undefined ) { 5523 if ( ( event.result = ret ) === false ) { 5524 event.preventDefault(); 5525 event.stopPropagation(); 5526 } 5527 } 5528 } 5529 } 5530 } 5531 5532 // Call the postDispatch hook for the mapped type 5533 if ( special.postDispatch ) { 5534 special.postDispatch.call( this, event ); 5535 } 5536 5537 return event.result; 5538 }, 5539 5540 handlers: function( event, handlers ) { 5541 var i, handleObj, sel, matchedHandlers, matchedSelectors, 5542 handlerQueue = [], 5543 delegateCount = handlers.delegateCount, 5544 cur = event.target; 5545 5546 // Find delegate handlers 5547 if ( delegateCount && 5548 5549 // Support: IE <=9 5550 // Black-hole SVG <use> instance trees (trac-13180) 5551 cur.nodeType && 5552 5553 // Support: Firefox <=42 5554 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 5555 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 5556 // Support: IE 11 only 5557 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 5558 !( event.type === "click" && event.button >= 1 ) ) { 5559 5560 for ( ; cur !== this; cur = cur.parentNode || this ) { 5561 5562 // Don't check non-elements (#13208) 5563 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 5564 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 5565 matchedHandlers = []; 5566 matchedSelectors = {}; 5567 for ( i = 0; i < delegateCount; i++ ) { 5568 handleObj = handlers[ i ]; 5569 5570 // Don't conflict with Object.prototype properties (#13203) 5571 sel = handleObj.selector + " "; 5572 5573 if ( matchedSelectors[ sel ] === undefined ) { 5574 matchedSelectors[ sel ] = handleObj.needsContext ? 5575 jQuery( sel, this ).index( cur ) > -1 : 5576 jQuery.find( sel, this, null, [ cur ] ).length; 5577 } 5578 if ( matchedSelectors[ sel ] ) { 5579 matchedHandlers.push( handleObj ); 5580 } 5581 } 5582 if ( matchedHandlers.length ) { 5583 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 5584 } 5585 } 5586 } 5587 } 5588 5589 // Add the remaining (directly-bound) handlers 5590 cur = this; 5591 if ( delegateCount < handlers.length ) { 5592 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 5593 } 5594 5595 return handlerQueue; 5596 }, 5597 5598 addProp: function( name, hook ) { 5599 Object.defineProperty( jQuery.Event.prototype, name, { 5600 enumerable: true, 5601 configurable: true, 5602 5603 get: isFunction( hook ) ? 5604 function() { 5605 if ( this.originalEvent ) { 5606 return hook( this.originalEvent ); 5607 } 5608 } : 5609 function() { 5610 if ( this.originalEvent ) { 5611 return this.originalEvent[ name ]; 5612 } 5613 }, 5614 5615 set: function( value ) { 5616 Object.defineProperty( this, name, { 5617 enumerable: true, 5618 configurable: true, 5619 writable: true, 5620 value: value 5621 } ); 5622 } 5623 } ); 5624 }, 5625 5626 fix: function( originalEvent ) { 5627 return originalEvent[ jQuery.expando ] ? 5628 originalEvent : 5629 new jQuery.Event( originalEvent ); 5630 }, 5631 5632 special: { 5633 load: { 5634 5635 // Prevent triggered image.load events from bubbling to window.load 5636 noBubble: true 5637 }, 5638 click: { 5639 5640 // Utilize native event to ensure correct state for checkable inputs 5641 setup: function( data ) { 5642 5643 // For mutual compressibility with _default, replace `this` access with a local var. 5644 // `|| data` is dead code meant only to preserve the variable through minification. 5645 var el = this || data; 5646 5647 // Claim the first handler 5648 if ( rcheckableType.test( el.type ) && 5649 el.click && nodeName( el, "input" ) ) { 5650 5651 // dataPriv.set( el, "click", ... ) 5652 leverageNative( el, "click", returnTrue ); 5653 } 5654 5655 // Return false to allow normal processing in the caller 5656 return false; 5657 }, 5658 trigger: function( data ) { 5659 5660 // For mutual compressibility with _default, replace `this` access with a local var. 5661 // `|| data` is dead code meant only to preserve the variable through minification. 5662 var el = this || data; 5663 5664 // Force setup before triggering a click 5665 if ( rcheckableType.test( el.type ) && 5666 el.click && nodeName( el, "input" ) ) { 5667 5668 leverageNative( el, "click" ); 5669 } 5670 5671 // Return non-false to allow normal event-path propagation 5672 return true; 5673 }, 5674 5675 // For cross-browser consistency, suppress native .click() on links 5676 // Also prevent it if we're currently inside a leveraged native-event stack 5677 _default: function( event ) { 5678 var target = event.target; 5679 return rcheckableType.test( target.type ) && 5680 target.click && nodeName( target, "input" ) && 5681 dataPriv.get( target, "click" ) || 5682 nodeName( target, "a" ); 5683 } 5684 }, 5685 5686 beforeunload: { 5687 postDispatch: function( event ) { 5688 5689 // Support: Firefox 20+ 5690 // Firefox doesn't alert if the returnValue field is not set. 5691 if ( event.result !== undefined && event.originalEvent ) { 5692 event.originalEvent.returnValue = event.result; 5693 } 5694 } 5695 } 5696 } 5697}; 5698 5699// Ensure the presence of an event listener that handles manually-triggered 5700// synthetic events by interrupting progress until reinvoked in response to 5701// *native* events that it fires directly, ensuring that state changes have 5702// already occurred before other listeners are invoked. 5703function leverageNative( el, type, expectSync ) { 5704 5705 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 5706 if ( !expectSync ) { 5707 if ( dataPriv.get( el, type ) === undefined ) { 5708 jQuery.event.add( el, type, returnTrue ); 5709 } 5710 return; 5711 } 5712 5713 // Register the controller as a special universal handler for all event namespaces 5714 dataPriv.set( el, type, false ); 5715 jQuery.event.add( el, type, { 5716 namespace: false, 5717 handler: function( event ) { 5718 var notAsync, result, 5719 saved = dataPriv.get( this, type ); 5720 5721 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 5722 5723 // Interrupt processing of the outer synthetic .trigger()ed event 5724 // Saved data should be false in such cases, but might be a leftover capture object 5725 // from an async native handler (gh-4350) 5726 if ( !saved.length ) { 5727 5728 // Store arguments for use when handling the inner native event 5729 // There will always be at least one argument (an event object), so this array 5730 // will not be confused with a leftover capture object. 5731 saved = slice.call( arguments ); 5732 dataPriv.set( this, type, saved ); 5733 5734 // Trigger the native event and capture its result 5735 // Support: IE <=9 - 11+ 5736 // focus() and blur() are asynchronous 5737 notAsync = expectSync( this, type ); 5738 this[ type ](); 5739 result = dataPriv.get( this, type ); 5740 if ( saved !== result || notAsync ) { 5741 dataPriv.set( this, type, false ); 5742 } else { 5743 result = {}; 5744 } 5745 if ( saved !== result ) { 5746 5747 // Cancel the outer synthetic event 5748 event.stopImmediatePropagation(); 5749 event.preventDefault(); 5750 5751 // Support: Chrome 86+ 5752 // In Chrome, if an element having a focusout handler is blurred by 5753 // clicking outside of it, it invokes the handler synchronously. If 5754 // that handler calls `.remove()` on the element, the data is cleared, 5755 // leaving `result` undefined. We need to guard against this. 5756 return result && result.value; 5757 } 5758 5759 // If this is an inner synthetic event for an event with a bubbling surrogate 5760 // (focus or blur), assume that the surrogate already propagated from triggering the 5761 // native event and prevent that from happening again here. 5762 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 5763 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 5764 // less bad than duplication. 5765 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 5766 event.stopPropagation(); 5767 } 5768 5769 // If this is a native event triggered above, everything is now in order 5770 // Fire an inner synthetic event with the original arguments 5771 } else if ( saved.length ) { 5772 5773 // ...and capture the result 5774 dataPriv.set( this, type, { 5775 value: jQuery.event.trigger( 5776 5777 // Support: IE <=9 - 11+ 5778 // Extend with the prototype to reset the above stopImmediatePropagation() 5779 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 5780 saved.slice( 1 ), 5781 this 5782 ) 5783 } ); 5784 5785 // Abort handling of the native event 5786 event.stopImmediatePropagation(); 5787 } 5788 } 5789 } ); 5790} 5791 5792jQuery.removeEvent = function( elem, type, handle ) { 5793 5794 // This "if" is needed for plain objects 5795 if ( elem.removeEventListener ) { 5796 elem.removeEventListener( type, handle ); 5797 } 5798}; 5799 5800jQuery.Event = function( src, props ) { 5801 5802 // Allow instantiation without the 'new' keyword 5803 if ( !( this instanceof jQuery.Event ) ) { 5804 return new jQuery.Event( src, props ); 5805 } 5806 5807 // Event object 5808 if ( src && src.type ) { 5809 this.originalEvent = src; 5810 this.type = src.type; 5811 5812 // Events bubbling up the document may have been marked as prevented 5813 // by a handler lower down the tree; reflect the correct value. 5814 this.isDefaultPrevented = src.defaultPrevented || 5815 src.defaultPrevented === undefined && 5816 5817 // Support: Android <=2.3 only 5818 src.returnValue === false ? 5819 returnTrue : 5820 returnFalse; 5821 5822 // Create target properties 5823 // Support: Safari <=6 - 7 only 5824 // Target should not be a text node (#504, #13143) 5825 this.target = ( src.target && src.target.nodeType === 3 ) ? 5826 src.target.parentNode : 5827 src.target; 5828 5829 this.currentTarget = src.currentTarget; 5830 this.relatedTarget = src.relatedTarget; 5831 5832 // Event type 5833 } else { 5834 this.type = src; 5835 } 5836 5837 // Put explicitly provided properties onto the event object 5838 if ( props ) { 5839 jQuery.extend( this, props ); 5840 } 5841 5842 // Create a timestamp if incoming event doesn't have one 5843 this.timeStamp = src && src.timeStamp || Date.now(); 5844 5845 // Mark it as fixed 5846 this[ jQuery.expando ] = true; 5847}; 5848 5849// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5850// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5851jQuery.Event.prototype = { 5852 constructor: jQuery.Event, 5853 isDefaultPrevented: returnFalse, 5854 isPropagationStopped: returnFalse, 5855 isImmediatePropagationStopped: returnFalse, 5856 isSimulated: false, 5857 5858 preventDefault: function() { 5859 var e = this.originalEvent; 5860 5861 this.isDefaultPrevented = returnTrue; 5862 5863 if ( e && !this.isSimulated ) { 5864 e.preventDefault(); 5865 } 5866 }, 5867 stopPropagation: function() { 5868 var e = this.originalEvent; 5869 5870 this.isPropagationStopped = returnTrue; 5871 5872 if ( e && !this.isSimulated ) { 5873 e.stopPropagation(); 5874 } 5875 }, 5876 stopImmediatePropagation: function() { 5877 var e = this.originalEvent; 5878 5879 this.isImmediatePropagationStopped = returnTrue; 5880 5881 if ( e && !this.isSimulated ) { 5882 e.stopImmediatePropagation(); 5883 } 5884 5885 this.stopPropagation(); 5886 } 5887}; 5888 5889// Includes all common event props including KeyEvent and MouseEvent specific props 5890jQuery.each( { 5891 altKey: true, 5892 bubbles: true, 5893 cancelable: true, 5894 changedTouches: true, 5895 ctrlKey: true, 5896 detail: true, 5897 eventPhase: true, 5898 metaKey: true, 5899 pageX: true, 5900 pageY: true, 5901 shiftKey: true, 5902 view: true, 5903 "char": true, 5904 code: true, 5905 charCode: true, 5906 key: true, 5907 keyCode: true, 5908 button: true, 5909 buttons: true, 5910 clientX: true, 5911 clientY: true, 5912 offsetX: true, 5913 offsetY: true, 5914 pointerId: true, 5915 pointerType: true, 5916 screenX: true, 5917 screenY: true, 5918 targetTouches: true, 5919 toElement: true, 5920 touches: true, 5921 which: true 5922}, jQuery.event.addProp ); 5923 5924jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 5925 jQuery.event.special[ type ] = { 5926 5927 // Utilize native event if possible so blur/focus sequence is correct 5928 setup: function() { 5929 5930 // Claim the first handler 5931 // dataPriv.set( this, "focus", ... ) 5932 // dataPriv.set( this, "blur", ... ) 5933 leverageNative( this, type, expectSync ); 5934 5935 // Return false to allow normal processing in the caller 5936 return false; 5937 }, 5938 trigger: function() { 5939 5940 // Force setup before trigger 5941 leverageNative( this, type ); 5942 5943 // Return non-false to allow normal event-path propagation 5944 return true; 5945 }, 5946 5947 // Suppress native focus or blur as it's already being fired 5948 // in leverageNative. 5949 _default: function() { 5950 return true; 5951 }, 5952 5953 delegateType: delegateType 5954 }; 5955} ); 5956 5957// Create mouseenter/leave events using mouseover/out and event-time checks 5958// so that event delegation works in jQuery. 5959// Do the same for pointerenter/pointerleave and pointerover/pointerout 5960// 5961// Support: Safari 7 only 5962// Safari sends mouseenter too often; see: 5963// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 5964// for the description of the bug (it existed in older Chrome versions as well). 5965jQuery.each( { 5966 mouseenter: "mouseover", 5967 mouseleave: "mouseout", 5968 pointerenter: "pointerover", 5969 pointerleave: "pointerout" 5970}, function( orig, fix ) { 5971 jQuery.event.special[ orig ] = { 5972 delegateType: fix, 5973 bindType: fix, 5974 5975 handle: function( event ) { 5976 var ret, 5977 target = this, 5978 related = event.relatedTarget, 5979 handleObj = event.handleObj; 5980 5981 // For mouseenter/leave call the handler if related is outside the target. 5982 // NB: No relatedTarget if the mouse left/entered the browser window 5983 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 5984 event.type = handleObj.origType; 5985 ret = handleObj.handler.apply( this, arguments ); 5986 event.type = fix; 5987 } 5988 return ret; 5989 } 5990 }; 5991} ); 5992 5993jQuery.fn.extend( { 5994 5995 on: function( types, selector, data, fn ) { 5996 return on( this, types, selector, data, fn ); 5997 }, 5998 one: function( types, selector, data, fn ) { 5999 return on( this, types, selector, data, fn, 1 ); 6000 }, 6001 off: function( types, selector, fn ) { 6002 var handleObj, type; 6003 if ( types && types.preventDefault && types.handleObj ) { 6004 6005 // ( event ) dispatched jQuery.Event 6006 handleObj = types.handleObj; 6007 jQuery( types.delegateTarget ).off( 6008 handleObj.namespace ? 6009 handleObj.origType + "." + handleObj.namespace : 6010 handleObj.origType, 6011 handleObj.selector, 6012 handleObj.handler 6013 ); 6014 return this; 6015 } 6016 if ( typeof types === "object" ) { 6017 6018 // ( types-object [, selector] ) 6019 for ( type in types ) { 6020 this.off( type, selector, types[ type ] ); 6021 } 6022 return this; 6023 } 6024 if ( selector === false || typeof selector === "function" ) { 6025 6026 // ( types [, fn] ) 6027 fn = selector; 6028 selector = undefined; 6029 } 6030 if ( fn === false ) { 6031 fn = returnFalse; 6032 } 6033 return this.each( function() { 6034 jQuery.event.remove( this, types, fn, selector ); 6035 } ); 6036 } 6037} ); 6038 6039 6040var 6041 6042 // Support: IE <=10 - 11, Edge 12 - 13 only 6043 // In IE/Edge using regex groups here causes severe slowdowns. 6044 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 6045 rnoInnerhtml = /<script|<style|<link/i, 6046 6047 // checked="checked" or checked 6048 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 6049 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 6050 6051// Prefer a tbody over its parent table for containing new rows 6052function manipulationTarget( elem, content ) { 6053 if ( nodeName( elem, "table" ) && 6054 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 6055 6056 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 6057 } 6058 6059 return elem; 6060} 6061 6062// Replace/restore the type attribute of script elements for safe DOM manipulation 6063function disableScript( elem ) { 6064 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 6065 return elem; 6066} 6067function restoreScript( elem ) { 6068 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 6069 elem.type = elem.type.slice( 5 ); 6070 } else { 6071 elem.removeAttribute( "type" ); 6072 } 6073 6074 return elem; 6075} 6076 6077function cloneCopyEvent( src, dest ) { 6078 var i, l, type, pdataOld, udataOld, udataCur, events; 6079 6080 if ( dest.nodeType !== 1 ) { 6081 return; 6082 } 6083 6084 // 1. Copy private data: events, handlers, etc. 6085 if ( dataPriv.hasData( src ) ) { 6086 pdataOld = dataPriv.get( src ); 6087 events = pdataOld.events; 6088 6089 if ( events ) { 6090 dataPriv.remove( dest, "handle events" ); 6091 6092 for ( type in events ) { 6093 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 6094 jQuery.event.add( dest, type, events[ type ][ i ] ); 6095 } 6096 } 6097 } 6098 } 6099 6100 // 2. Copy user data 6101 if ( dataUser.hasData( src ) ) { 6102 udataOld = dataUser.access( src ); 6103 udataCur = jQuery.extend( {}, udataOld ); 6104 6105 dataUser.set( dest, udataCur ); 6106 } 6107} 6108 6109// Fix IE bugs, see support tests 6110function fixInput( src, dest ) { 6111 var nodeName = dest.nodeName.toLowerCase(); 6112 6113 // Fails to persist the checked state of a cloned checkbox or radio button. 6114 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 6115 dest.checked = src.checked; 6116 6117 // Fails to return the selected option to the default selected state when cloning options 6118 } else if ( nodeName === "input" || nodeName === "textarea" ) { 6119 dest.defaultValue = src.defaultValue; 6120 } 6121} 6122 6123function domManip( collection, args, callback, ignored ) { 6124 6125 // Flatten any nested arrays 6126 args = flat( args ); 6127 6128 var fragment, first, scripts, hasScripts, node, doc, 6129 i = 0, 6130 l = collection.length, 6131 iNoClone = l - 1, 6132 value = args[ 0 ], 6133 valueIsFunction = isFunction( value ); 6134 6135 // We can't cloneNode fragments that contain checked, in WebKit 6136 if ( valueIsFunction || 6137 ( l > 1 && typeof value === "string" && 6138 !support.checkClone && rchecked.test( value ) ) ) { 6139 return collection.each( function( index ) { 6140 var self = collection.eq( index ); 6141 if ( valueIsFunction ) { 6142 args[ 0 ] = value.call( this, index, self.html() ); 6143 } 6144 domManip( self, args, callback, ignored ); 6145 } ); 6146 } 6147 6148 if ( l ) { 6149 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 6150 first = fragment.firstChild; 6151 6152 if ( fragment.childNodes.length === 1 ) { 6153 fragment = first; 6154 } 6155 6156 // Require either new content or an interest in ignored elements to invoke the callback 6157 if ( first || ignored ) { 6158 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 6159 hasScripts = scripts.length; 6160 6161 // Use the original fragment for the last item 6162 // instead of the first because it can end up 6163 // being emptied incorrectly in certain situations (#8070). 6164 for ( ; i < l; i++ ) { 6165 node = fragment; 6166 6167 if ( i !== iNoClone ) { 6168 node = jQuery.clone( node, true, true ); 6169 6170 // Keep references to cloned scripts for later restoration 6171 if ( hasScripts ) { 6172 6173 // Support: Android <=4.0 only, PhantomJS 1 only 6174 // push.apply(_, arraylike) throws on ancient WebKit 6175 jQuery.merge( scripts, getAll( node, "script" ) ); 6176 } 6177 } 6178 6179 callback.call( collection[ i ], node, i ); 6180 } 6181 6182 if ( hasScripts ) { 6183 doc = scripts[ scripts.length - 1 ].ownerDocument; 6184 6185 // Reenable scripts 6186 jQuery.map( scripts, restoreScript ); 6187 6188 // Evaluate executable scripts on first document insertion 6189 for ( i = 0; i < hasScripts; i++ ) { 6190 node = scripts[ i ]; 6191 if ( rscriptType.test( node.type || "" ) && 6192 !dataPriv.access( node, "globalEval" ) && 6193 jQuery.contains( doc, node ) ) { 6194 6195 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 6196 6197 // Optional AJAX dependency, but won't run scripts if not present 6198 if ( jQuery._evalUrl && !node.noModule ) { 6199 jQuery._evalUrl( node.src, { 6200 nonce: node.nonce || node.getAttribute( "nonce" ) 6201 }, doc ); 6202 } 6203 } else { 6204 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 6205 } 6206 } 6207 } 6208 } 6209 } 6210 } 6211 6212 return collection; 6213} 6214 6215function remove( elem, selector, keepData ) { 6216 var node, 6217 nodes = selector ? jQuery.filter( selector, elem ) : elem, 6218 i = 0; 6219 6220 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 6221 if ( !keepData && node.nodeType === 1 ) { 6222 jQuery.cleanData( getAll( node ) ); 6223 } 6224 6225 if ( node.parentNode ) { 6226 if ( keepData && isAttached( node ) ) { 6227 setGlobalEval( getAll( node, "script" ) ); 6228 } 6229 node.parentNode.removeChild( node ); 6230 } 6231 } 6232 6233 return elem; 6234} 6235 6236jQuery.extend( { 6237 htmlPrefilter: function( html ) { 6238 return html; 6239 }, 6240 6241 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 6242 var i, l, srcElements, destElements, 6243 clone = elem.cloneNode( true ), 6244 inPage = isAttached( elem ); 6245 6246 // Fix IE cloning issues 6247 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 6248 !jQuery.isXMLDoc( elem ) ) { 6249 6250 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 6251 destElements = getAll( clone ); 6252 srcElements = getAll( elem ); 6253 6254 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6255 fixInput( srcElements[ i ], destElements[ i ] ); 6256 } 6257 } 6258 6259 // Copy the events from the original to the clone 6260 if ( dataAndEvents ) { 6261 if ( deepDataAndEvents ) { 6262 srcElements = srcElements || getAll( elem ); 6263 destElements = destElements || getAll( clone ); 6264 6265 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6266 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 6267 } 6268 } else { 6269 cloneCopyEvent( elem, clone ); 6270 } 6271 } 6272 6273 // Preserve script evaluation history 6274 destElements = getAll( clone, "script" ); 6275 if ( destElements.length > 0 ) { 6276 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 6277 } 6278 6279 // Return the cloned set 6280 return clone; 6281 }, 6282 6283 cleanData: function( elems ) { 6284 var data, elem, type, 6285 special = jQuery.event.special, 6286 i = 0; 6287 6288 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 6289 if ( acceptData( elem ) ) { 6290 if ( ( data = elem[ dataPriv.expando ] ) ) { 6291 if ( data.events ) { 6292 for ( type in data.events ) { 6293 if ( special[ type ] ) { 6294 jQuery.event.remove( elem, type ); 6295 6296 // This is a shortcut to avoid jQuery.event.remove's overhead 6297 } else { 6298 jQuery.removeEvent( elem, type, data.handle ); 6299 } 6300 } 6301 } 6302 6303 // Support: Chrome <=35 - 45+ 6304 // Assign undefined instead of using delete, see Data#remove 6305 elem[ dataPriv.expando ] = undefined; 6306 } 6307 if ( elem[ dataUser.expando ] ) { 6308 6309 // Support: Chrome <=35 - 45+ 6310 // Assign undefined instead of using delete, see Data#remove 6311 elem[ dataUser.expando ] = undefined; 6312 } 6313 } 6314 } 6315 } 6316} ); 6317 6318jQuery.fn.extend( { 6319 detach: function( selector ) { 6320 return remove( this, selector, true ); 6321 }, 6322 6323 remove: function( selector ) { 6324 return remove( this, selector ); 6325 }, 6326 6327 text: function( value ) { 6328 return access( this, function( value ) { 6329 return value === undefined ? 6330 jQuery.text( this ) : 6331 this.empty().each( function() { 6332 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6333 this.textContent = value; 6334 } 6335 } ); 6336 }, null, value, arguments.length ); 6337 }, 6338 6339 append: function() { 6340 return domManip( this, arguments, function( elem ) { 6341 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6342 var target = manipulationTarget( this, elem ); 6343 target.appendChild( elem ); 6344 } 6345 } ); 6346 }, 6347 6348 prepend: function() { 6349 return domManip( this, arguments, function( elem ) { 6350 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6351 var target = manipulationTarget( this, elem ); 6352 target.insertBefore( elem, target.firstChild ); 6353 } 6354 } ); 6355 }, 6356 6357 before: function() { 6358 return domManip( this, arguments, function( elem ) { 6359 if ( this.parentNode ) { 6360 this.parentNode.insertBefore( elem, this ); 6361 } 6362 } ); 6363 }, 6364 6365 after: function() { 6366 return domManip( this, arguments, function( elem ) { 6367 if ( this.parentNode ) { 6368 this.parentNode.insertBefore( elem, this.nextSibling ); 6369 } 6370 } ); 6371 }, 6372 6373 empty: function() { 6374 var elem, 6375 i = 0; 6376 6377 for ( ; ( elem = this[ i ] ) != null; i++ ) { 6378 if ( elem.nodeType === 1 ) { 6379 6380 // Prevent memory leaks 6381 jQuery.cleanData( getAll( elem, false ) ); 6382 6383 // Remove any remaining nodes 6384 elem.textContent = ""; 6385 } 6386 } 6387 6388 return this; 6389 }, 6390 6391 clone: function( dataAndEvents, deepDataAndEvents ) { 6392 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6393 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6394 6395 return this.map( function() { 6396 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 6397 } ); 6398 }, 6399 6400 html: function( value ) { 6401 return access( this, function( value ) { 6402 var elem = this[ 0 ] || {}, 6403 i = 0, 6404 l = this.length; 6405 6406 if ( value === undefined && elem.nodeType === 1 ) { 6407 return elem.innerHTML; 6408 } 6409 6410 // See if we can take a shortcut and just use innerHTML 6411 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 6412 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 6413 6414 value = jQuery.htmlPrefilter( value ); 6415 6416 try { 6417 for ( ; i < l; i++ ) { 6418 elem = this[ i ] || {}; 6419 6420 // Remove element nodes and prevent memory leaks 6421 if ( elem.nodeType === 1 ) { 6422 jQuery.cleanData( getAll( elem, false ) ); 6423 elem.innerHTML = value; 6424 } 6425 } 6426 6427 elem = 0; 6428 6429 // If using innerHTML throws an exception, use the fallback method 6430 } catch ( e ) {} 6431 } 6432 6433 if ( elem ) { 6434 this.empty().append( value ); 6435 } 6436 }, null, value, arguments.length ); 6437 }, 6438 6439 replaceWith: function() { 6440 var ignored = []; 6441 6442 // Make the changes, replacing each non-ignored context element with the new content 6443 return domManip( this, arguments, function( elem ) { 6444 var parent = this.parentNode; 6445 6446 if ( jQuery.inArray( this, ignored ) < 0 ) { 6447 jQuery.cleanData( getAll( this ) ); 6448 if ( parent ) { 6449 parent.replaceChild( elem, this ); 6450 } 6451 } 6452 6453 // Force callback invocation 6454 }, ignored ); 6455 } 6456} ); 6457 6458jQuery.each( { 6459 appendTo: "append", 6460 prependTo: "prepend", 6461 insertBefore: "before", 6462 insertAfter: "after", 6463 replaceAll: "replaceWith" 6464}, function( name, original ) { 6465 jQuery.fn[ name ] = function( selector ) { 6466 var elems, 6467 ret = [], 6468 insert = jQuery( selector ), 6469 last = insert.length - 1, 6470 i = 0; 6471 6472 for ( ; i <= last; i++ ) { 6473 elems = i === last ? this : this.clone( true ); 6474 jQuery( insert[ i ] )[ original ]( elems ); 6475 6476 // Support: Android <=4.0 only, PhantomJS 1 only 6477 // .get() because push.apply(_, arraylike) throws on ancient WebKit 6478 push.apply( ret, elems.get() ); 6479 } 6480 6481 return this.pushStack( ret ); 6482 }; 6483} ); 6484var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 6485 6486var getStyles = function( elem ) { 6487 6488 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 6489 // IE throws on elements created in popups 6490 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6491 var view = elem.ownerDocument.defaultView; 6492 6493 if ( !view || !view.opener ) { 6494 view = window; 6495 } 6496 6497 return view.getComputedStyle( elem ); 6498 }; 6499 6500var swap = function( elem, options, callback ) { 6501 var ret, name, 6502 old = {}; 6503 6504 // Remember the old values, and insert the new ones 6505 for ( name in options ) { 6506 old[ name ] = elem.style[ name ]; 6507 elem.style[ name ] = options[ name ]; 6508 } 6509 6510 ret = callback.call( elem ); 6511 6512 // Revert the old values 6513 for ( name in options ) { 6514 elem.style[ name ] = old[ name ]; 6515 } 6516 6517 return ret; 6518}; 6519 6520 6521var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 6522 6523 6524 6525( function() { 6526 6527 // Executing both pixelPosition & boxSizingReliable tests require only one layout 6528 // so they're executed at the same time to save the second computation. 6529 function computeStyleTests() { 6530 6531 // This is a singleton, we need to execute it only once 6532 if ( !div ) { 6533 return; 6534 } 6535 6536 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 6537 "margin-top:1px;padding:0;border:0"; 6538 div.style.cssText = 6539 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 6540 "margin:auto;border:1px;padding:1px;" + 6541 "width:60%;top:1%"; 6542 documentElement.appendChild( container ).appendChild( div ); 6543 6544 var divStyle = window.getComputedStyle( div ); 6545 pixelPositionVal = divStyle.top !== "1%"; 6546 6547 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 6548 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 6549 6550 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 6551 // Some styles come back with percentage values, even though they shouldn't 6552 div.style.right = "60%"; 6553 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 6554 6555 // Support: IE 9 - 11 only 6556 // Detect misreporting of content dimensions for box-sizing:border-box elements 6557 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 6558 6559 // Support: IE 9 only 6560 // Detect overflow:scroll screwiness (gh-3699) 6561 // Support: Chrome <=64 6562 // Don't get tricked when zoom affects offsetWidth (gh-4029) 6563 div.style.position = "absolute"; 6564 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 6565 6566 documentElement.removeChild( container ); 6567 6568 // Nullify the div so it wouldn't be stored in the memory and 6569 // it will also be a sign that checks already performed 6570 div = null; 6571 } 6572 6573 function roundPixelMeasures( measure ) { 6574 return Math.round( parseFloat( measure ) ); 6575 } 6576 6577 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 6578 reliableTrDimensionsVal, reliableMarginLeftVal, 6579 container = document.createElement( "div" ), 6580 div = document.createElement( "div" ); 6581 6582 // Finish early in limited (non-browser) environments 6583 if ( !div.style ) { 6584 return; 6585 } 6586 6587 // Support: IE <=9 - 11 only 6588 // Style of cloned element affects source element cloned (#8908) 6589 div.style.backgroundClip = "content-box"; 6590 div.cloneNode( true ).style.backgroundClip = ""; 6591 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6592 6593 jQuery.extend( support, { 6594 boxSizingReliable: function() { 6595 computeStyleTests(); 6596 return boxSizingReliableVal; 6597 }, 6598 pixelBoxStyles: function() { 6599 computeStyleTests(); 6600 return pixelBoxStylesVal; 6601 }, 6602 pixelPosition: function() { 6603 computeStyleTests(); 6604 return pixelPositionVal; 6605 }, 6606 reliableMarginLeft: function() { 6607 computeStyleTests(); 6608 return reliableMarginLeftVal; 6609 }, 6610 scrollboxSize: function() { 6611 computeStyleTests(); 6612 return scrollboxSizeVal; 6613 }, 6614 6615 // Support: IE 9 - 11+, Edge 15 - 18+ 6616 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6617 // set in CSS while `offset*` properties report correct values. 6618 // Behavior in IE 9 is more subtle than in newer versions & it passes 6619 // some versions of this test; make sure not to make it pass there! 6620 // 6621 // Support: Firefox 70+ 6622 // Only Firefox includes border widths 6623 // in computed dimensions. (gh-4529) 6624 reliableTrDimensions: function() { 6625 var table, tr, trChild, trStyle; 6626 if ( reliableTrDimensionsVal == null ) { 6627 table = document.createElement( "table" ); 6628 tr = document.createElement( "tr" ); 6629 trChild = document.createElement( "div" ); 6630 6631 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 6632 tr.style.cssText = "border:1px solid"; 6633 6634 // Support: Chrome 86+ 6635 // Height set through cssText does not get applied. 6636 // Computed height then comes back as 0. 6637 tr.style.height = "1px"; 6638 trChild.style.height = "9px"; 6639 6640 // Support: Android 8 Chrome 86+ 6641 // In our bodyBackground.html iframe, 6642 // display for all div elements is set to "inline", 6643 // which causes a problem only in Android 8 Chrome 86. 6644 // Ensuring the div is display: block 6645 // gets around this issue. 6646 trChild.style.display = "block"; 6647 6648 documentElement 6649 .appendChild( table ) 6650 .appendChild( tr ) 6651 .appendChild( trChild ); 6652 6653 trStyle = window.getComputedStyle( tr ); 6654 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 6655 parseInt( trStyle.borderTopWidth, 10 ) + 6656 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 6657 6658 documentElement.removeChild( table ); 6659 } 6660 return reliableTrDimensionsVal; 6661 } 6662 } ); 6663} )(); 6664 6665 6666function curCSS( elem, name, computed ) { 6667 var width, minWidth, maxWidth, ret, 6668 6669 // Support: Firefox 51+ 6670 // Retrieving style before computed somehow 6671 // fixes an issue with getting wrong values 6672 // on detached elements 6673 style = elem.style; 6674 6675 computed = computed || getStyles( elem ); 6676 6677 // getPropertyValue is needed for: 6678 // .css('filter') (IE 9 only, #12537) 6679 // .css('--customProperty) (#3144) 6680 if ( computed ) { 6681 ret = computed.getPropertyValue( name ) || computed[ name ]; 6682 6683 if ( ret === "" && !isAttached( elem ) ) { 6684 ret = jQuery.style( elem, name ); 6685 } 6686 6687 // A tribute to the "awesome hack by Dean Edwards" 6688 // Android Browser returns percentage for some values, 6689 // but width seems to be reliably pixels. 6690 // This is against the CSSOM draft spec: 6691 // https://drafts.csswg.org/cssom/#resolved-values 6692 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 6693 6694 // Remember the original values 6695 width = style.width; 6696 minWidth = style.minWidth; 6697 maxWidth = style.maxWidth; 6698 6699 // Put in the new values to get a computed value out 6700 style.minWidth = style.maxWidth = style.width = ret; 6701 ret = computed.width; 6702 6703 // Revert the changed values 6704 style.width = width; 6705 style.minWidth = minWidth; 6706 style.maxWidth = maxWidth; 6707 } 6708 } 6709 6710 return ret !== undefined ? 6711 6712 // Support: IE <=9 - 11 only 6713 // IE returns zIndex value as an integer. 6714 ret + "" : 6715 ret; 6716} 6717 6718 6719function addGetHookIf( conditionFn, hookFn ) { 6720 6721 // Define the hook, we'll check on the first run if it's really needed. 6722 return { 6723 get: function() { 6724 if ( conditionFn() ) { 6725 6726 // Hook not needed (or it's not possible to use it due 6727 // to missing dependency), remove it. 6728 delete this.get; 6729 return; 6730 } 6731 6732 // Hook needed; redefine it so that the support test is not executed again. 6733 return ( this.get = hookFn ).apply( this, arguments ); 6734 } 6735 }; 6736} 6737 6738 6739var cssPrefixes = [ "Webkit", "Moz", "ms" ], 6740 emptyStyle = document.createElement( "div" ).style, 6741 vendorProps = {}; 6742 6743// Return a vendor-prefixed property or undefined 6744function vendorPropName( name ) { 6745 6746 // Check for vendor prefixed names 6747 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 6748 i = cssPrefixes.length; 6749 6750 while ( i-- ) { 6751 name = cssPrefixes[ i ] + capName; 6752 if ( name in emptyStyle ) { 6753 return name; 6754 } 6755 } 6756} 6757 6758// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 6759function finalPropName( name ) { 6760 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 6761 6762 if ( final ) { 6763 return final; 6764 } 6765 if ( name in emptyStyle ) { 6766 return name; 6767 } 6768 return vendorProps[ name ] = vendorPropName( name ) || name; 6769} 6770 6771 6772var 6773 6774 // Swappable if display is none or starts with table 6775 // except "table", "table-cell", or "table-caption" 6776 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 6777 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6778 rcustomProp = /^--/, 6779 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6780 cssNormalTransform = { 6781 letterSpacing: "0", 6782 fontWeight: "400" 6783 }; 6784 6785function setPositiveNumber( _elem, value, subtract ) { 6786 6787 // Any relative (+/-) values have already been 6788 // normalized at this point 6789 var matches = rcssNum.exec( value ); 6790 return matches ? 6791 6792 // Guard against undefined "subtract", e.g., when used as in cssHooks 6793 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 6794 value; 6795} 6796 6797function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 6798 var i = dimension === "width" ? 1 : 0, 6799 extra = 0, 6800 delta = 0; 6801 6802 // Adjustment may not be necessary 6803 if ( box === ( isBorderBox ? "border" : "content" ) ) { 6804 return 0; 6805 } 6806 6807 for ( ; i < 4; i += 2 ) { 6808 6809 // Both box models exclude margin 6810 if ( box === "margin" ) { 6811 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 6812 } 6813 6814 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 6815 if ( !isBorderBox ) { 6816 6817 // Add padding 6818 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6819 6820 // For "border" or "margin", add border 6821 if ( box !== "padding" ) { 6822 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6823 6824 // But still keep track of it otherwise 6825 } else { 6826 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6827 } 6828 6829 // If we get here with a border-box (content + padding + border), we're seeking "content" or 6830 // "padding" or "margin" 6831 } else { 6832 6833 // For "content", subtract padding 6834 if ( box === "content" ) { 6835 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6836 } 6837 6838 // For "content" or "padding", subtract border 6839 if ( box !== "margin" ) { 6840 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6841 } 6842 } 6843 } 6844 6845 // Account for positive content-box scroll gutter when requested by providing computedVal 6846 if ( !isBorderBox && computedVal >= 0 ) { 6847 6848 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 6849 // Assuming integer scroll gutter, subtract the rest and round down 6850 delta += Math.max( 0, Math.ceil( 6851 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6852 computedVal - 6853 delta - 6854 extra - 6855 0.5 6856 6857 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 6858 // Use an explicit zero to avoid NaN (gh-3964) 6859 ) ) || 0; 6860 } 6861 6862 return delta; 6863} 6864 6865function getWidthOrHeight( elem, dimension, extra ) { 6866 6867 // Start with computed style 6868 var styles = getStyles( elem ), 6869 6870 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 6871 // Fake content-box until we know it's needed to know the true value. 6872 boxSizingNeeded = !support.boxSizingReliable() || extra, 6873 isBorderBox = boxSizingNeeded && 6874 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6875 valueIsBorderBox = isBorderBox, 6876 6877 val = curCSS( elem, dimension, styles ), 6878 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 6879 6880 // Support: Firefox <=54 6881 // Return a confounding non-pixel value or feign ignorance, as appropriate. 6882 if ( rnumnonpx.test( val ) ) { 6883 if ( !extra ) { 6884 return val; 6885 } 6886 val = "auto"; 6887 } 6888 6889 6890 // Support: IE 9 - 11 only 6891 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 6892 // In those cases, the computed value can be trusted to be border-box. 6893 if ( ( !support.boxSizingReliable() && isBorderBox || 6894 6895 // Support: IE 10 - 11+, Edge 15 - 18+ 6896 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6897 // set in CSS while `offset*` properties report correct values. 6898 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 6899 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 6900 6901 // Fall back to offsetWidth/offsetHeight when value is "auto" 6902 // This happens for inline elements with no explicit setting (gh-3571) 6903 val === "auto" || 6904 6905 // Support: Android <=4.1 - 4.3 only 6906 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 6907 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 6908 6909 // Make sure the element is visible & connected 6910 elem.getClientRects().length ) { 6911 6912 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 6913 6914 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 6915 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 6916 // retrieved value as a content box dimension. 6917 valueIsBorderBox = offsetProp in elem; 6918 if ( valueIsBorderBox ) { 6919 val = elem[ offsetProp ]; 6920 } 6921 } 6922 6923 // Normalize "" and auto 6924 val = parseFloat( val ) || 0; 6925 6926 // Adjust for the element's box model 6927 return ( val + 6928 boxModelAdjustment( 6929 elem, 6930 dimension, 6931 extra || ( isBorderBox ? "border" : "content" ), 6932 valueIsBorderBox, 6933 styles, 6934 6935 // Provide the current computed size to request scroll gutter calculation (gh-3589) 6936 val 6937 ) 6938 ) + "px"; 6939} 6940 6941jQuery.extend( { 6942 6943 // Add in style property hooks for overriding the default 6944 // behavior of getting and setting a style property 6945 cssHooks: { 6946 opacity: { 6947 get: function( elem, computed ) { 6948 if ( computed ) { 6949 6950 // We should always get a number back from opacity 6951 var ret = curCSS( elem, "opacity" ); 6952 return ret === "" ? "1" : ret; 6953 } 6954 } 6955 } 6956 }, 6957 6958 // Don't automatically add "px" to these possibly-unitless properties 6959 cssNumber: { 6960 "animationIterationCount": true, 6961 "columnCount": true, 6962 "fillOpacity": true, 6963 "flexGrow": true, 6964 "flexShrink": true, 6965 "fontWeight": true, 6966 "gridArea": true, 6967 "gridColumn": true, 6968 "gridColumnEnd": true, 6969 "gridColumnStart": true, 6970 "gridRow": true, 6971 "gridRowEnd": true, 6972 "gridRowStart": true, 6973 "lineHeight": true, 6974 "opacity": true, 6975 "order": true, 6976 "orphans": true, 6977 "widows": true, 6978 "zIndex": true, 6979 "zoom": true 6980 }, 6981 6982 // Add in properties whose names you wish to fix before 6983 // setting or getting the value 6984 cssProps: {}, 6985 6986 // Get and set the style property on a DOM Node 6987 style: function( elem, name, value, extra ) { 6988 6989 // Don't set styles on text and comment nodes 6990 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6991 return; 6992 } 6993 6994 // Make sure that we're working with the right name 6995 var ret, type, hooks, 6996 origName = camelCase( name ), 6997 isCustomProp = rcustomProp.test( name ), 6998 style = elem.style; 6999 7000 // Make sure that we're working with the right name. We don't 7001 // want to query the value if it is a CSS custom property 7002 // since they are user-defined. 7003 if ( !isCustomProp ) { 7004 name = finalPropName( origName ); 7005 } 7006 7007 // Gets hook for the prefixed version, then unprefixed version 7008 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 7009 7010 // Check if we're setting a value 7011 if ( value !== undefined ) { 7012 type = typeof value; 7013 7014 // Convert "+=" or "-=" to relative numbers (#7345) 7015 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 7016 value = adjustCSS( elem, name, ret ); 7017 7018 // Fixes bug #9237 7019 type = "number"; 7020 } 7021 7022 // Make sure that null and NaN values aren't set (#7116) 7023 if ( value == null || value !== value ) { 7024 return; 7025 } 7026 7027 // If a number was passed in, add the unit (except for certain CSS properties) 7028 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 7029 // "px" to a few hardcoded values. 7030 if ( type === "number" && !isCustomProp ) { 7031 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 7032 } 7033 7034 // background-* props affect original clone's values 7035 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 7036 style[ name ] = "inherit"; 7037 } 7038 7039 // If a hook was provided, use that value, otherwise just set the specified value
vendor: 25,692 bytes, lines 7040-8036
7040 if ( !hooks || !( "set" in hooks ) || 7041 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 7042 7043 if ( isCustomProp ) { 7044 style.setProperty( name, value ); 7045 } else { 7046 style[ name ] = value; 7047 } 7048 } 7049 7050 } else { 7051 7052 // If a hook was provided get the non-computed value from there 7053 if ( hooks && "get" in hooks && 7054 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 7055 7056 return ret; 7057 } 7058 7059 // Otherwise just get the value from the style object 7060 return style[ name ]; 7061 } 7062 }, 7063 7064 css: function( elem, name, extra, styles ) { 7065 var val, num, hooks, 7066 origName = camelCase( name ), 7067 isCustomProp = rcustomProp.test( name ); 7068 7069 // Make sure that we're working with the right name. We don't 7070 // want to modify the value if it is a CSS custom property 7071 // since they are user-defined. 7072 if ( !isCustomProp ) { 7073 name = finalPropName( origName ); 7074 } 7075 7076 // Try prefixed name followed by the unprefixed name 7077 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 7078 7079 // If a hook was provided get the computed value from there 7080 if ( hooks && "get" in hooks ) { 7081 val = hooks.get( elem, true, extra ); 7082 } 7083 7084 // Otherwise, if a way to get the computed value exists, use that 7085 if ( val === undefined ) { 7086 val = curCSS( elem, name, styles ); 7087 } 7088 7089 // Convert "normal" to computed value 7090 if ( val === "normal" && name in cssNormalTransform ) { 7091 val = cssNormalTransform[ name ]; 7092 } 7093 7094 // Make numeric if forced or a qualifier was provided and val looks numeric 7095 if ( extra === "" || extra ) { 7096 num = parseFloat( val ); 7097 return extra === true || isFinite( num ) ? num || 0 : val; 7098 } 7099 7100 return val; 7101 } 7102} ); 7103 7104jQuery.each( [ "height", "width" ], function( _i, dimension ) { 7105 jQuery.cssHooks[ dimension ] = { 7106 get: function( elem, computed, extra ) { 7107 if ( computed ) { 7108 7109 // Certain elements can have dimension info if we invisibly show them 7110 // but it must have a current display style that would benefit 7111 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 7112 7113 // Support: Safari 8+ 7114 // Table columns in Safari have non-zero offsetWidth & zero 7115 // getBoundingClientRect().width unless display is changed. 7116 // Support: IE <=11 only 7117 // Running getBoundingClientRect on a disconnected node 7118 // in IE throws an error. 7119 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 7120 swap( elem, cssShow, function() { 7121 return getWidthOrHeight( elem, dimension, extra ); 7122 } ) : 7123 getWidthOrHeight( elem, dimension, extra ); 7124 } 7125 }, 7126 7127 set: function( elem, value, extra ) { 7128 var matches, 7129 styles = getStyles( elem ), 7130 7131 // Only read styles.position if the test has a chance to fail 7132 // to avoid forcing a reflow. 7133 scrollboxSizeBuggy = !support.scrollboxSize() && 7134 styles.position === "absolute", 7135 7136 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 7137 boxSizingNeeded = scrollboxSizeBuggy || extra, 7138 isBorderBox = boxSizingNeeded && 7139 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 7140 subtract = extra ? 7141 boxModelAdjustment( 7142 elem, 7143 dimension, 7144 extra, 7145 isBorderBox, 7146 styles 7147 ) : 7148 0; 7149 7150 // Account for unreliable border-box dimensions by comparing offset* to computed and 7151 // faking a content-box to get border and padding (gh-3699) 7152 if ( isBorderBox && scrollboxSizeBuggy ) { 7153 subtract -= Math.ceil( 7154 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 7155 parseFloat( styles[ dimension ] ) - 7156 boxModelAdjustment( elem, dimension, "border", false, styles ) - 7157 0.5 7158 ); 7159 } 7160 7161 // Convert to pixels if value adjustment is needed 7162 if ( subtract && ( matches = rcssNum.exec( value ) ) && 7163 ( matches[ 3 ] || "px" ) !== "px" ) { 7164 7165 elem.style[ dimension ] = value; 7166 value = jQuery.css( elem, dimension ); 7167 } 7168 7169 return setPositiveNumber( elem, value, subtract ); 7170 } 7171 }; 7172} ); 7173 7174jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 7175 function( elem, computed ) { 7176 if ( computed ) { 7177 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 7178 elem.getBoundingClientRect().left - 7179 swap( elem, { marginLeft: 0 }, function() { 7180 return elem.getBoundingClientRect().left; 7181 } ) 7182 ) + "px"; 7183 } 7184 } 7185); 7186 7187// These hooks are used by animate to expand properties 7188jQuery.each( { 7189 margin: "", 7190 padding: "", 7191 border: "Width" 7192}, function( prefix, suffix ) { 7193 jQuery.cssHooks[ prefix + suffix ] = { 7194 expand: function( value ) { 7195 var i = 0, 7196 expanded = {}, 7197 7198 // Assumes a single number if not a string 7199 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 7200 7201 for ( ; i < 4; i++ ) { 7202 expanded[ prefix + cssExpand[ i ] + suffix ] = 7203 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 7204 } 7205 7206 return expanded; 7207 } 7208 }; 7209 7210 if ( prefix !== "margin" ) { 7211 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 7212 } 7213} ); 7214 7215jQuery.fn.extend( { 7216 css: function( name, value ) { 7217 return access( this, function( elem, name, value ) { 7218 var styles, len, 7219 map = {}, 7220 i = 0; 7221 7222 if ( Array.isArray( name ) ) { 7223 styles = getStyles( elem ); 7224 len = name.length; 7225 7226 for ( ; i < len; i++ ) { 7227 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 7228 } 7229 7230 return map; 7231 } 7232 7233 return value !== undefined ? 7234 jQuery.style( elem, name, value ) : 7235 jQuery.css( elem, name ); 7236 }, name, value, arguments.length > 1 ); 7237 } 7238} ); 7239 7240 7241function Tween( elem, options, prop, end, easing ) { 7242 return new Tween.prototype.init( elem, options, prop, end, easing ); 7243} 7244jQuery.Tween = Tween; 7245 7246Tween.prototype = { 7247 constructor: Tween, 7248 init: function( elem, options, prop, end, easing, unit ) { 7249 this.elem = elem; 7250 this.prop = prop; 7251 this.easing = easing || jQuery.easing._default; 7252 this.options = options; 7253 this.start = this.now = this.cur(); 7254 this.end = end; 7255 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 7256 }, 7257 cur: function() { 7258 var hooks = Tween.propHooks[ this.prop ]; 7259 7260 return hooks && hooks.get ? 7261 hooks.get( this ) : 7262 Tween.propHooks._default.get( this ); 7263 }, 7264 run: function( percent ) { 7265 var eased, 7266 hooks = Tween.propHooks[ this.prop ]; 7267 7268 if ( this.options.duration ) { 7269 this.pos = eased = jQuery.easing[ this.easing ]( 7270 percent, this.options.duration * percent, 0, 1, this.options.duration 7271 ); 7272 } else { 7273 this.pos = eased = percent; 7274 } 7275 this.now = ( this.end - this.start ) * eased + this.start; 7276 7277 if ( this.options.step ) { 7278 this.options.step.call( this.elem, this.now, this ); 7279 } 7280 7281 if ( hooks && hooks.set ) { 7282 hooks.set( this ); 7283 } else { 7284 Tween.propHooks._default.set( this ); 7285 } 7286 return this; 7287 } 7288}; 7289 7290Tween.prototype.init.prototype = Tween.prototype; 7291 7292Tween.propHooks = { 7293 _default: { 7294 get: function( tween ) { 7295 var result; 7296 7297 // Use a property on the element directly when it is not a DOM element, 7298 // or when there is no matching style property that exists. 7299 if ( tween.elem.nodeType !== 1 || 7300 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 7301 return tween.elem[ tween.prop ]; 7302 } 7303 7304 // Passing an empty string as a 3rd parameter to .css will automatically 7305 // attempt a parseFloat and fallback to a string if the parse fails. 7306 // Simple values such as "10px" are parsed to Float; 7307 // complex values such as "rotate(1rad)" are returned as-is. 7308 result = jQuery.css( tween.elem, tween.prop, "" ); 7309 7310 // Empty strings, null, undefined and "auto" are converted to 0. 7311 return !result || result === "auto" ? 0 : result; 7312 }, 7313 set: function( tween ) { 7314 7315 // Use step hook for back compat. 7316 // Use cssHook if its there. 7317 // Use .style if available and use plain properties where available. 7318 if ( jQuery.fx.step[ tween.prop ] ) { 7319 jQuery.fx.step[ tween.prop ]( tween ); 7320 } else if ( tween.elem.nodeType === 1 && ( 7321 jQuery.cssHooks[ tween.prop ] || 7322 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 7323 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 7324 } else { 7325 tween.elem[ tween.prop ] = tween.now; 7326 } 7327 } 7328 } 7329}; 7330 7331// Support: IE <=9 only 7332// Panic based approach to setting things on disconnected nodes 7333Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7334 set: function( tween ) { 7335 if ( tween.elem.nodeType && tween.elem.parentNode ) { 7336 tween.elem[ tween.prop ] = tween.now; 7337 } 7338 } 7339}; 7340 7341jQuery.easing = { 7342 linear: function( p ) { 7343 return p; 7344 }, 7345 swing: function( p ) { 7346 return 0.5 - Math.cos( p * Math.PI ) / 2; 7347 }, 7348 _default: "swing" 7349}; 7350 7351jQuery.fx = Tween.prototype.init; 7352 7353// Back compat <1.8 extension point 7354jQuery.fx.step = {}; 7355 7356 7357 7358 7359var 7360 fxNow, inProgress, 7361 rfxtypes = /^(?:toggle|show|hide)$/, 7362 rrun = /queueHooks$/; 7363 7364function schedule() { 7365 if ( inProgress ) { 7366 if ( document.hidden === false && window.requestAnimationFrame ) { 7367 window.requestAnimationFrame( schedule ); 7368 } else { 7369 window.setTimeout( schedule, jQuery.fx.interval ); 7370 } 7371 7372 jQuery.fx.tick(); 7373 } 7374} 7375 7376// Animations created synchronously will run synchronously 7377function createFxNow() { 7378 window.setTimeout( function() { 7379 fxNow = undefined; 7380 } ); 7381 return ( fxNow = Date.now() ); 7382} 7383 7384// Generate parameters to create a standard animation 7385function genFx( type, includeWidth ) { 7386 var which, 7387 i = 0, 7388 attrs = { height: type }; 7389 7390 // If we include width, step value is 1 to do all cssExpand values, 7391 // otherwise step value is 2 to skip over Left and Right 7392 includeWidth = includeWidth ? 1 : 0; 7393 for ( ; i < 4; i += 2 - includeWidth ) { 7394 which = cssExpand[ i ]; 7395 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 7396 } 7397 7398 if ( includeWidth ) { 7399 attrs.opacity = attrs.width = type; 7400 } 7401 7402 return attrs; 7403} 7404 7405function createTween( value, prop, animation ) { 7406 var tween, 7407 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 7408 index = 0, 7409 length = collection.length; 7410 for ( ; index < length; index++ ) { 7411 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 7412 7413 // We're done with this property 7414 return tween; 7415 } 7416 } 7417} 7418 7419function defaultPrefilter( elem, props, opts ) { 7420 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 7421 isBox = "width" in props || "height" in props, 7422 anim = this, 7423 orig = {}, 7424 style = elem.style, 7425 hidden = elem.nodeType && isHiddenWithinTree( elem ), 7426 dataShow = dataPriv.get( elem, "fxshow" ); 7427 7428 // Queue-skipping animations hijack the fx hooks 7429 if ( !opts.queue ) { 7430 hooks = jQuery._queueHooks( elem, "fx" ); 7431 if ( hooks.unqueued == null ) { 7432 hooks.unqueued = 0; 7433 oldfire = hooks.empty.fire; 7434 hooks.empty.fire = function() { 7435 if ( !hooks.unqueued ) { 7436 oldfire(); 7437 } 7438 }; 7439 } 7440 hooks.unqueued++; 7441 7442 anim.always( function() { 7443 7444 // Ensure the complete handler is called before this completes 7445 anim.always( function() { 7446 hooks.unqueued--; 7447 if ( !jQuery.queue( elem, "fx" ).length ) { 7448 hooks.empty.fire(); 7449 } 7450 } ); 7451 } ); 7452 } 7453 7454 // Detect show/hide animations 7455 for ( prop in props ) { 7456 value = props[ prop ]; 7457 if ( rfxtypes.test( value ) ) { 7458 delete props[ prop ]; 7459 toggle = toggle || value === "toggle"; 7460 if ( value === ( hidden ? "hide" : "show" ) ) { 7461 7462 // Pretend to be hidden if this is a "show" and 7463 // there is still data from a stopped show/hide 7464 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 7465 hidden = true; 7466 7467 // Ignore all other no-op show/hide data 7468 } else { 7469 continue; 7470 } 7471 } 7472 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 7473 } 7474 } 7475 7476 // Bail out if this is a no-op like .hide().hide() 7477 propTween = !jQuery.isEmptyObject( props ); 7478 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 7479 return; 7480 } 7481 7482 // Restrict "overflow" and "display" styles during box animations 7483 if ( isBox && elem.nodeType === 1 ) { 7484 7485 // Support: IE <=9 - 11, Edge 12 - 15 7486 // Record all 3 overflow attributes because IE does not infer the shorthand 7487 // from identically-valued overflowX and overflowY and Edge just mirrors 7488 // the overflowX value there. 7489 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 7490 7491 // Identify a display type, preferring old show/hide data over the CSS cascade 7492 restoreDisplay = dataShow && dataShow.display; 7493 if ( restoreDisplay == null ) { 7494 restoreDisplay = dataPriv.get( elem, "display" ); 7495 } 7496 display = jQuery.css( elem, "display" ); 7497 if ( display === "none" ) { 7498 if ( restoreDisplay ) { 7499 display = restoreDisplay; 7500 } else { 7501 7502 // Get nonempty value(s) by temporarily forcing visibility 7503 showHide( [ elem ], true ); 7504 restoreDisplay = elem.style.display || restoreDisplay; 7505 display = jQuery.css( elem, "display" ); 7506 showHide( [ elem ] ); 7507 } 7508 } 7509 7510 // Animate inline elements as inline-block 7511 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 7512 if ( jQuery.css( elem, "float" ) === "none" ) { 7513 7514 // Restore the original display value at the end of pure show/hide animations 7515 if ( !propTween ) { 7516 anim.done( function() { 7517 style.display = restoreDisplay; 7518 } ); 7519 if ( restoreDisplay == null ) { 7520 display = style.display; 7521 restoreDisplay = display === "none" ? "" : display; 7522 } 7523 } 7524 style.display = "inline-block"; 7525 } 7526 } 7527 } 7528 7529 if ( opts.overflow ) { 7530 style.overflow = "hidden"; 7531 anim.always( function() { 7532 style.overflow = opts.overflow[ 0 ]; 7533 style.overflowX = opts.overflow[ 1 ]; 7534 style.overflowY = opts.overflow[ 2 ]; 7535 } ); 7536 } 7537 7538 // Implement show/hide animations 7539 propTween = false; 7540 for ( prop in orig ) { 7541 7542 // General show/hide setup for this element animation 7543 if ( !propTween ) { 7544 if ( dataShow ) { 7545 if ( "hidden" in dataShow ) { 7546 hidden = dataShow.hidden; 7547 } 7548 } else { 7549 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 7550 } 7551 7552 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 7553 if ( toggle ) { 7554 dataShow.hidden = !hidden; 7555 } 7556 7557 // Show elements before animating them 7558 if ( hidden ) { 7559 showHide( [ elem ], true ); 7560 } 7561 7562 /* eslint-disable no-loop-func */ 7563 7564 anim.done( function() { 7565 7566 /* eslint-enable no-loop-func */ 7567 7568 // The final step of a "hide" animation is actually hiding the element 7569 if ( !hidden ) { 7570 showHide( [ elem ] ); 7571 } 7572 dataPriv.remove( elem, "fxshow" ); 7573 for ( prop in orig ) { 7574 jQuery.style( elem, prop, orig[ prop ] ); 7575 } 7576 } ); 7577 } 7578 7579 // Per-property setup 7580 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 7581 if ( !( prop in dataShow ) ) { 7582 dataShow[ prop ] = propTween.start; 7583 if ( hidden ) { 7584 propTween.end = propTween.start; 7585 propTween.start = 0; 7586 } 7587 } 7588 } 7589} 7590 7591function propFilter( props, specialEasing ) { 7592 var index, name, easing, value, hooks; 7593 7594 // camelCase, specialEasing and expand cssHook pass 7595 for ( index in props ) { 7596 name = camelCase( index ); 7597 easing = specialEasing[ name ]; 7598 value = props[ index ]; 7599 if ( Array.isArray( value ) ) { 7600 easing = value[ 1 ]; 7601 value = props[ index ] = value[ 0 ]; 7602 } 7603 7604 if ( index !== name ) { 7605 props[ name ] = value; 7606 delete props[ index ]; 7607 } 7608 7609 hooks = jQuery.cssHooks[ name ]; 7610 if ( hooks && "expand" in hooks ) { 7611 value = hooks.expand( value ); 7612 delete props[ name ]; 7613 7614 // Not quite $.extend, this won't overwrite existing keys. 7615 // Reusing 'index' because we have the correct "name" 7616 for ( index in value ) { 7617 if ( !( index in props ) ) { 7618 props[ index ] = value[ index ]; 7619 specialEasing[ index ] = easing; 7620 } 7621 } 7622 } else { 7623 specialEasing[ name ] = easing; 7624 } 7625 } 7626} 7627 7628function Animation( elem, properties, options ) { 7629 var result, 7630 stopped, 7631 index = 0, 7632 length = Animation.prefilters.length, 7633 deferred = jQuery.Deferred().always( function() { 7634 7635 // Don't match elem in the :animated selector 7636 delete tick.elem; 7637 } ), 7638 tick = function() { 7639 if ( stopped ) { 7640 return false; 7641 } 7642 var currentTime = fxNow || createFxNow(), 7643 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 7644 7645 // Support: Android 2.3 only 7646 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 7647 temp = remaining / animation.duration || 0, 7648 percent = 1 - temp, 7649 index = 0, 7650 length = animation.tweens.length; 7651 7652 for ( ; index < length; index++ ) { 7653 animation.tweens[ index ].run( percent ); 7654 } 7655 7656 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 7657 7658 // If there's more to do, yield 7659 if ( percent < 1 && length ) { 7660 return remaining; 7661 } 7662 7663 // If this was an empty animation, synthesize a final progress notification 7664 if ( !length ) { 7665 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7666 } 7667 7668 // Resolve the animation and report its conclusion 7669 deferred.resolveWith( elem, [ animation ] ); 7670 return false; 7671 }, 7672 animation = deferred.promise( { 7673 elem: elem, 7674 props: jQuery.extend( {}, properties ), 7675 opts: jQuery.extend( true, { 7676 specialEasing: {}, 7677 easing: jQuery.easing._default 7678 }, options ), 7679 originalProperties: properties, 7680 originalOptions: options, 7681 startTime: fxNow || createFxNow(), 7682 duration: options.duration, 7683 tweens: [], 7684 createTween: function( prop, end ) { 7685 var tween = jQuery.Tween( elem, animation.opts, prop, end, 7686 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 7687 animation.tweens.push( tween ); 7688 return tween; 7689 }, 7690 stop: function( gotoEnd ) { 7691 var index = 0, 7692 7693 // If we are going to the end, we want to run all the tweens 7694 // otherwise we skip this part 7695 length = gotoEnd ? animation.tweens.length : 0; 7696 if ( stopped ) { 7697 return this; 7698 } 7699 stopped = true; 7700 for ( ; index < length; index++ ) { 7701 animation.tweens[ index ].run( 1 ); 7702 } 7703 7704 // Resolve when we played the last frame; otherwise, reject 7705 if ( gotoEnd ) { 7706 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7707 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 7708 } else { 7709 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 7710 } 7711 return this; 7712 } 7713 } ), 7714 props = animation.props; 7715 7716 propFilter( props, animation.opts.specialEasing ); 7717 7718 for ( ; index < length; index++ ) { 7719 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 7720 if ( result ) { 7721 if ( isFunction( result.stop ) ) { 7722 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 7723 result.stop.bind( result ); 7724 } 7725 return result; 7726 } 7727 } 7728 7729 jQuery.map( props, createTween, animation ); 7730 7731 if ( isFunction( animation.opts.start ) ) { 7732 animation.opts.start.call( elem, animation ); 7733 } 7734 7735 // Attach callbacks from options 7736 animation 7737 .progress( animation.opts.progress ) 7738 .done( animation.opts.done, animation.opts.complete ) 7739 .fail( animation.opts.fail ) 7740 .always( animation.opts.always ); 7741 7742 jQuery.fx.timer( 7743 jQuery.extend( tick, { 7744 elem: elem, 7745 anim: animation, 7746 queue: animation.opts.queue 7747 } ) 7748 ); 7749 7750 return animation; 7751} 7752 7753jQuery.Animation = jQuery.extend( Animation, { 7754 7755 tweeners: { 7756 "*": [ function( prop, value ) { 7757 var tween = this.createTween( prop, value ); 7758 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 7759 return tween; 7760 } ] 7761 }, 7762 7763 tweener: function( props, callback ) { 7764 if ( isFunction( props ) ) { 7765 callback = props; 7766 props = [ "*" ]; 7767 } else { 7768 props = props.match( rnothtmlwhite ); 7769 } 7770 7771 var prop, 7772 index = 0, 7773 length = props.length; 7774 7775 for ( ; index < length; index++ ) { 7776 prop = props[ index ]; 7777 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 7778 Animation.tweeners[ prop ].unshift( callback ); 7779 } 7780 }, 7781 7782 prefilters: [ defaultPrefilter ], 7783 7784 prefilter: function( callback, prepend ) { 7785 if ( prepend ) { 7786 Animation.prefilters.unshift( callback ); 7787 } else { 7788 Animation.prefilters.push( callback ); 7789 } 7790 } 7791} ); 7792 7793jQuery.speed = function( speed, easing, fn ) { 7794 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 7795 complete: fn || !fn && easing || 7796 isFunction( speed ) && speed, 7797 duration: speed, 7798 easing: fn && easing || easing && !isFunction( easing ) && easing 7799 }; 7800 7801 // Go to the end state if fx are off 7802 if ( jQuery.fx.off ) { 7803 opt.duration = 0; 7804 7805 } else { 7806 if ( typeof opt.duration !== "number" ) { 7807 if ( opt.duration in jQuery.fx.speeds ) { 7808 opt.duration = jQuery.fx.speeds[ opt.duration ]; 7809 7810 } else { 7811 opt.duration = jQuery.fx.speeds._default; 7812 } 7813 } 7814 } 7815 7816 // Normalize opt.queue - true/undefined/null -> "fx" 7817 if ( opt.queue == null || opt.queue === true ) { 7818 opt.queue = "fx"; 7819 } 7820 7821 // Queueing 7822 opt.old = opt.complete; 7823 7824 opt.complete = function() { 7825 if ( isFunction( opt.old ) ) { 7826 opt.old.call( this ); 7827 } 7828 7829 if ( opt.queue ) { 7830 jQuery.dequeue( this, opt.queue ); 7831 } 7832 }; 7833 7834 return opt; 7835}; 7836 7837jQuery.fn.extend( { 7838 fadeTo: function( speed, to, easing, callback ) { 7839 7840 // Show any hidden elements after setting opacity to 0 7841 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 7842 7843 // Animate to the value specified 7844 .end().animate( { opacity: to }, speed, easing, callback ); 7845 }, 7846 animate: function( prop, speed, easing, callback ) { 7847 var empty = jQuery.isEmptyObject( prop ), 7848 optall = jQuery.speed( speed, easing, callback ), 7849 doAnimation = function() { 7850 7851 // Operate on a copy of prop so per-property easing won't be lost 7852 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 7853 7854 // Empty animations, or finishing resolves immediately 7855 if ( empty || dataPriv.get( this, "finish" ) ) { 7856 anim.stop( true ); 7857 } 7858 }; 7859 7860 doAnimation.finish = doAnimation; 7861 7862 return empty || optall.queue === false ? 7863 this.each( doAnimation ) : 7864 this.queue( optall.queue, doAnimation ); 7865 }, 7866 stop: function( type, clearQueue, gotoEnd ) { 7867 var stopQueue = function( hooks ) { 7868 var stop = hooks.stop; 7869 delete hooks.stop; 7870 stop( gotoEnd ); 7871 }; 7872 7873 if ( typeof type !== "string" ) { 7874 gotoEnd = clearQueue; 7875 clearQueue = type; 7876 type = undefined; 7877 } 7878 if ( clearQueue ) { 7879 this.queue( type || "fx", [] ); 7880 } 7881 7882 return this.each( function() { 7883 var dequeue = true, 7884 index = type != null && type + "queueHooks", 7885 timers = jQuery.timers, 7886 data = dataPriv.get( this ); 7887 7888 if ( index ) { 7889 if ( data[ index ] && data[ index ].stop ) { 7890 stopQueue( data[ index ] ); 7891 } 7892 } else { 7893 for ( index in data ) { 7894 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 7895 stopQueue( data[ index ] ); 7896 } 7897 } 7898 } 7899 7900 for ( index = timers.length; index--; ) { 7901 if ( timers[ index ].elem === this && 7902 ( type == null || timers[ index ].queue === type ) ) { 7903 7904 timers[ index ].anim.stop( gotoEnd ); 7905 dequeue = false; 7906 timers.splice( index, 1 ); 7907 } 7908 } 7909 7910 // Start the next in the queue if the last step wasn't forced. 7911 // Timers currently will call their complete callbacks, which 7912 // will dequeue but only if they were gotoEnd. 7913 if ( dequeue || !gotoEnd ) { 7914 jQuery.dequeue( this, type ); 7915 } 7916 } ); 7917 }, 7918 finish: function( type ) { 7919 if ( type !== false ) { 7920 type = type || "fx"; 7921 } 7922 return this.each( function() { 7923 var index, 7924 data = dataPriv.get( this ), 7925 queue = data[ type + "queue" ], 7926 hooks = data[ type + "queueHooks" ], 7927 timers = jQuery.timers, 7928 length = queue ? queue.length : 0; 7929 7930 // Enable finishing flag on private data 7931 data.finish = true; 7932 7933 // Empty the queue first 7934 jQuery.queue( this, type, [] ); 7935 7936 if ( hooks && hooks.stop ) { 7937 hooks.stop.call( this, true ); 7938 } 7939 7940 // Look for any active animations, and finish them 7941 for ( index = timers.length; index--; ) { 7942 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 7943 timers[ index ].anim.stop( true ); 7944 timers.splice( index, 1 ); 7945 } 7946 } 7947 7948 // Look for any animations in the old queue and finish them 7949 for ( index = 0; index < length; index++ ) { 7950 if ( queue[ index ] && queue[ index ].finish ) { 7951 queue[ index ].finish.call( this ); 7952 } 7953 } 7954 7955 // Turn off finishing flag 7956 delete data.finish; 7957 } ); 7958 } 7959} ); 7960 7961jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 7962 var cssFn = jQuery.fn[ name ]; 7963 jQuery.fn[ name ] = function( speed, easing, callback ) { 7964 return speed == null || typeof speed === "boolean" ? 7965 cssFn.apply( this, arguments ) : 7966 this.animate( genFx( name, true ), speed, easing, callback ); 7967 }; 7968} ); 7969 7970// Generate shortcuts for custom animations 7971jQuery.each( { 7972 slideDown: genFx( "show" ), 7973 slideUp: genFx( "hide" ), 7974 slideToggle: genFx( "toggle" ), 7975 fadeIn: { opacity: "show" }, 7976 fadeOut: { opacity: "hide" }, 7977 fadeToggle: { opacity: "toggle" } 7978}, function( name, props ) { 7979 jQuery.fn[ name ] = function( speed, easing, callback ) { 7980 return this.animate( props, speed, easing, callback ); 7981 }; 7982} ); 7983 7984jQuery.timers = []; 7985jQuery.fx.tick = function() { 7986 var timer, 7987 i = 0, 7988 timers = jQuery.timers; 7989 7990 fxNow = Date.now(); 7991 7992 for ( ; i < timers.length; i++ ) { 7993 timer = timers[ i ]; 7994 7995 // Run the timer and safely remove it when done (allowing for external removal) 7996 if ( !timer() && timers[ i ] === timer ) { 7997 timers.splice( i--, 1 ); 7998 } 7999 } 8000 8001 if ( !timers.length ) { 8002 jQuery.fx.stop(); 8003 } 8004 fxNow = undefined; 8005}; 8006 8007jQuery.fx.timer = function( timer ) { 8008 jQuery.timers.push( timer ); 8009 jQuery.fx.start(); 8010}; 8011 8012jQuery.fx.interval = 13; 8013jQuery.fx.start = function() { 8014 if ( inProgress ) { 8015 return; 8016 } 8017 8018 inProgress = true; 8019 schedule(); 8020}; 8021 8022jQuery.fx.stop = function() { 8023 inProgress = null; 8024}; 8025 8026jQuery.fx.speeds = { 8027 slow: 600, 8028 fast: 200, 8029 8030 // Default speed 8031 _default: 400 8032}; 8033 8034 8035// Based off of the plugin by Clint Helfers, with permission. 8036// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
vendor: 21,001 bytes, lines 8037-8905
8037jQuery.fn.delay = function( time, type ) { 8038 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 8039 type = type || "fx"; 8040 8041 return this.queue( type, function( next, hooks ) { 8042 var timeout = window.setTimeout( next, time ); 8043 hooks.stop = function() { 8044 window.clearTimeout( timeout ); 8045 }; 8046 } ); 8047}; 8048 8049 8050( function() { 8051 var input = document.createElement( "input" ), 8052 select = document.createElement( "select" ), 8053 opt = select.appendChild( document.createElement( "option" ) ); 8054 8055 input.type = "checkbox"; 8056 8057 // Support: Android <=4.3 only 8058 // Default value for a checkbox should be "on" 8059 support.checkOn = input.value !== ""; 8060 8061 // Support: IE <=11 only 8062 // Must access selectedIndex to make default options select 8063 support.optSelected = opt.selected; 8064 8065 // Support: IE <=11 only 8066 // An input loses its value after becoming a radio 8067 input = document.createElement( "input" ); 8068 input.value = "t"; 8069 input.type = "radio"; 8070 support.radioValue = input.value === "t"; 8071} )(); 8072 8073 8074var boolHook, 8075 attrHandle = jQuery.expr.attrHandle; 8076 8077jQuery.fn.extend( { 8078 attr: function( name, value ) { 8079 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 8080 }, 8081 8082 removeAttr: function( name ) { 8083 return this.each( function() { 8084 jQuery.removeAttr( this, name ); 8085 } ); 8086 } 8087} ); 8088 8089jQuery.extend( { 8090 attr: function( elem, name, value ) { 8091 var ret, hooks, 8092 nType = elem.nodeType; 8093 8094 // Don't get/set attributes on text, comment and attribute nodes 8095 if ( nType === 3 || nType === 8 || nType === 2 ) { 8096 return; 8097 } 8098 8099 // Fallback to prop when attributes are not supported 8100 if ( typeof elem.getAttribute === "undefined" ) { 8101 return jQuery.prop( elem, name, value ); 8102 } 8103 8104 // Attribute hooks are determined by the lowercase version 8105 // Grab necessary hook if one is defined 8106 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8107 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 8108 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 8109 } 8110 8111 if ( value !== undefined ) { 8112 if ( value === null ) { 8113 jQuery.removeAttr( elem, name ); 8114 return; 8115 } 8116 8117 if ( hooks && "set" in hooks && 8118 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8119 return ret; 8120 } 8121 8122 elem.setAttribute( name, value + "" ); 8123 return value; 8124 } 8125 8126 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8127 return ret; 8128 } 8129 8130 ret = jQuery.find.attr( elem, name ); 8131 8132 // Non-existent attributes return null, we normalize to undefined 8133 return ret == null ? undefined : ret; 8134 }, 8135 8136 attrHooks: { 8137 type: { 8138 set: function( elem, value ) { 8139 if ( !support.radioValue && value === "radio" && 8140 nodeName( elem, "input" ) ) { 8141 var val = elem.value; 8142 elem.setAttribute( "type", value ); 8143 if ( val ) { 8144 elem.value = val; 8145 } 8146 return value; 8147 } 8148 } 8149 } 8150 }, 8151 8152 removeAttr: function( elem, value ) { 8153 var name, 8154 i = 0, 8155 8156 // Attribute names can contain non-HTML whitespace characters 8157 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 8158 attrNames = value && value.match( rnothtmlwhite ); 8159 8160 if ( attrNames && elem.nodeType === 1 ) { 8161 while ( ( name = attrNames[ i++ ] ) ) { 8162 elem.removeAttribute( name ); 8163 } 8164 } 8165 } 8166} ); 8167 8168// Hooks for boolean attributes 8169boolHook = { 8170 set: function( elem, value, name ) { 8171 if ( value === false ) { 8172 8173 // Remove boolean attributes when set to false 8174 jQuery.removeAttr( elem, name ); 8175 } else { 8176 elem.setAttribute( name, name ); 8177 } 8178 return name; 8179 } 8180}; 8181 8182jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 8183 var getter = attrHandle[ name ] || jQuery.find.attr; 8184 8185 attrHandle[ name ] = function( elem, name, isXML ) { 8186 var ret, handle, 8187 lowercaseName = name.toLowerCase(); 8188 8189 if ( !isXML ) { 8190 8191 // Avoid an infinite loop by temporarily removing this function from the getter 8192 handle = attrHandle[ lowercaseName ]; 8193 attrHandle[ lowercaseName ] = ret; 8194 ret = getter( elem, name, isXML ) != null ? 8195 lowercaseName : 8196 null; 8197 attrHandle[ lowercaseName ] = handle; 8198 } 8199 return ret; 8200 }; 8201} ); 8202 8203 8204 8205 8206var rfocusable = /^(?:input|select|textarea|button)$/i, 8207 rclickable = /^(?:a|area)$/i; 8208 8209jQuery.fn.extend( { 8210 prop: function( name, value ) { 8211 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 8212 }, 8213 8214 removeProp: function( name ) { 8215 return this.each( function() { 8216 delete this[ jQuery.propFix[ name ] || name ]; 8217 } ); 8218 } 8219} ); 8220 8221jQuery.extend( { 8222 prop: function( elem, name, value ) { 8223 var ret, hooks, 8224 nType = elem.nodeType; 8225 8226 // Don't get/set properties on text, comment and attribute nodes 8227 if ( nType === 3 || nType === 8 || nType === 2 ) { 8228 return; 8229 } 8230 8231 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8232 8233 // Fix name and attach hooks 8234 name = jQuery.propFix[ name ] || name; 8235 hooks = jQuery.propHooks[ name ]; 8236 } 8237 8238 if ( value !== undefined ) { 8239 if ( hooks && "set" in hooks && 8240 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8241 return ret; 8242 } 8243 8244 return ( elem[ name ] = value ); 8245 } 8246 8247 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8248 return ret; 8249 } 8250 8251 return elem[ name ]; 8252 }, 8253 8254 propHooks: { 8255 tabIndex: { 8256 get: function( elem ) { 8257 8258 // Support: IE <=9 - 11 only 8259 // elem.tabIndex doesn't always return the 8260 // correct value when it hasn't been explicitly set 8261 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 8262 // Use proper attribute retrieval(#12072) 8263 var tabindex = jQuery.find.attr( elem, "tabindex" ); 8264 8265 if ( tabindex ) { 8266 return parseInt( tabindex, 10 ); 8267 } 8268 8269 if ( 8270 rfocusable.test( elem.nodeName ) || 8271 rclickable.test( elem.nodeName ) && 8272 elem.href 8273 ) { 8274 return 0; 8275 } 8276 8277 return -1; 8278 } 8279 } 8280 }, 8281 8282 propFix: { 8283 "for": "htmlFor", 8284 "class": "className" 8285 } 8286} ); 8287 8288// Support: IE <=11 only 8289// Accessing the selectedIndex property 8290// forces the browser to respect setting selected 8291// on the option 8292// The getter ensures a default option is selected 8293// when in an optgroup 8294// eslint rule "no-unused-expressions" is disabled for this code 8295// since it considers such accessions noop 8296if ( !support.optSelected ) { 8297 jQuery.propHooks.selected = { 8298 get: function( elem ) { 8299 8300 /* eslint no-unused-expressions: "off" */ 8301 8302 var parent = elem.parentNode; 8303 if ( parent && parent.parentNode ) { 8304 parent.parentNode.selectedIndex; 8305 } 8306 return null; 8307 }, 8308 set: function( elem ) { 8309 8310 /* eslint no-unused-expressions: "off" */ 8311 8312 var parent = elem.parentNode; 8313 if ( parent ) { 8314 parent.selectedIndex; 8315 8316 if ( parent.parentNode ) { 8317 parent.parentNode.selectedIndex; 8318 } 8319 } 8320 } 8321 }; 8322} 8323 8324jQuery.each( [ 8325 "tabIndex", 8326 "readOnly", 8327 "maxLength", 8328 "cellSpacing", 8329 "cellPadding", 8330 "rowSpan", 8331 "colSpan", 8332 "useMap", 8333 "frameBorder", 8334 "contentEditable" 8335], function() { 8336 jQuery.propFix[ this.toLowerCase() ] = this; 8337} ); 8338 8339 8340 8341 8342 // Strip and collapse whitespace according to HTML spec 8343 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 8344 function stripAndCollapse( value ) { 8345 var tokens = value.match( rnothtmlwhite ) || []; 8346 return tokens.join( " " ); 8347 } 8348 8349 8350function getClass( elem ) { 8351 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 8352} 8353 8354function classesToArray( value ) { 8355 if ( Array.isArray( value ) ) { 8356 return value; 8357 } 8358 if ( typeof value === "string" ) { 8359 return value.match( rnothtmlwhite ) || []; 8360 } 8361 return []; 8362} 8363 8364jQuery.fn.extend( { 8365 addClass: function( value ) { 8366 var classes, elem, cur, curValue, clazz, j, finalValue, 8367 i = 0; 8368 8369 if ( isFunction( value ) ) { 8370 return this.each( function( j ) { 8371 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 8372 } ); 8373 } 8374 8375 classes = classesToArray( value ); 8376 8377 if ( classes.length ) { 8378 while ( ( elem = this[ i++ ] ) ) { 8379 curValue = getClass( elem ); 8380 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8381 8382 if ( cur ) { 8383 j = 0; 8384 while ( ( clazz = classes[ j++ ] ) ) { 8385 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 8386 cur += clazz + " "; 8387 } 8388 } 8389 8390 // Only assign if different to avoid unneeded rendering. 8391 finalValue = stripAndCollapse( cur ); 8392 if ( curValue !== finalValue ) { 8393 elem.setAttribute( "class", finalValue ); 8394 } 8395 } 8396 } 8397 } 8398 8399 return this; 8400 }, 8401 8402 removeClass: function( value ) { 8403 var classes, elem, cur, curValue, clazz, j, finalValue, 8404 i = 0; 8405 8406 if ( isFunction( value ) ) { 8407 return this.each( function( j ) { 8408 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 8409 } ); 8410 } 8411 8412 if ( !arguments.length ) { 8413 return this.attr( "class", "" ); 8414 } 8415 8416 classes = classesToArray( value ); 8417 8418 if ( classes.length ) { 8419 while ( ( elem = this[ i++ ] ) ) { 8420 curValue = getClass( elem ); 8421 8422 // This expression is here for better compressibility (see addClass) 8423 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8424 8425 if ( cur ) { 8426 j = 0; 8427 while ( ( clazz = classes[ j++ ] ) ) { 8428 8429 // Remove *all* instances 8430 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 8431 cur = cur.replace( " " + clazz + " ", " " ); 8432 } 8433 } 8434 8435 // Only assign if different to avoid unneeded rendering. 8436 finalValue = stripAndCollapse( cur ); 8437 if ( curValue !== finalValue ) { 8438 elem.setAttribute( "class", finalValue ); 8439 } 8440 } 8441 } 8442 } 8443 8444 return this; 8445 }, 8446 8447 toggleClass: function( value, stateVal ) { 8448 var type = typeof value, 8449 isValidValue = type === "string" || Array.isArray( value ); 8450 8451 if ( typeof stateVal === "boolean" && isValidValue ) { 8452 return stateVal ? this.addClass( value ) : this.removeClass( value ); 8453 } 8454 8455 if ( isFunction( value ) ) { 8456 return this.each( function( i ) { 8457 jQuery( this ).toggleClass( 8458 value.call( this, i, getClass( this ), stateVal ), 8459 stateVal 8460 ); 8461 } ); 8462 } 8463 8464 return this.each( function() { 8465 var className, i, self, classNames; 8466 8467 if ( isValidValue ) { 8468 8469 // Toggle individual class names 8470 i = 0; 8471 self = jQuery( this ); 8472 classNames = classesToArray( value ); 8473 8474 while ( ( className = classNames[ i++ ] ) ) { 8475 8476 // Check each className given, space separated list 8477 if ( self.hasClass( className ) ) { 8478 self.removeClass( className ); 8479 } else { 8480 self.addClass( className ); 8481 } 8482 } 8483 8484 // Toggle whole class name 8485 } else if ( value === undefined || type === "boolean" ) { 8486 className = getClass( this ); 8487 if ( className ) { 8488 8489 // Store className if set 8490 dataPriv.set( this, "__className__", className ); 8491 } 8492 8493 // If the element has a class name or if we're passed `false`, 8494 // then remove the whole classname (if there was one, the above saved it). 8495 // Otherwise bring back whatever was previously saved (if anything), 8496 // falling back to the empty string if nothing was stored. 8497 if ( this.setAttribute ) { 8498 this.setAttribute( "class", 8499 className || value === false ? 8500 "" : 8501 dataPriv.get( this, "__className__" ) || "" 8502 ); 8503 } 8504 } 8505 } ); 8506 }, 8507 8508 hasClass: function( selector ) { 8509 var className, elem, 8510 i = 0; 8511 8512 className = " " + selector + " "; 8513 while ( ( elem = this[ i++ ] ) ) { 8514 if ( elem.nodeType === 1 && 8515 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 8516 return true; 8517 } 8518 } 8519 8520 return false; 8521 } 8522} ); 8523 8524 8525 8526 8527var rreturn = /\r/g; 8528 8529jQuery.fn.extend( { 8530 val: function( value ) { 8531 var hooks, ret, valueIsFunction, 8532 elem = this[ 0 ]; 8533 8534 if ( !arguments.length ) { 8535 if ( elem ) { 8536 hooks = jQuery.valHooks[ elem.type ] || 8537 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 8538 8539 if ( hooks && 8540 "get" in hooks && 8541 ( ret = hooks.get( elem, "value" ) ) !== undefined 8542 ) { 8543 return ret; 8544 } 8545 8546 ret = elem.value; 8547 8548 // Handle most common string cases 8549 if ( typeof ret === "string" ) { 8550 return ret.replace( rreturn, "" ); 8551 } 8552 8553 // Handle cases where value is null/undef or number 8554 return ret == null ? "" : ret; 8555 } 8556 8557 return; 8558 } 8559 8560 valueIsFunction = isFunction( value ); 8561 8562 return this.each( function( i ) { 8563 var val; 8564 8565 if ( this.nodeType !== 1 ) { 8566 return; 8567 } 8568 8569 if ( valueIsFunction ) { 8570 val = value.call( this, i, jQuery( this ).val() ); 8571 } else { 8572 val = value; 8573 } 8574 8575 // Treat null/undefined as ""; convert numbers to string 8576 if ( val == null ) { 8577 val = ""; 8578 8579 } else if ( typeof val === "number" ) { 8580 val += ""; 8581 8582 } else if ( Array.isArray( val ) ) { 8583 val = jQuery.map( val, function( value ) { 8584 return value == null ? "" : value + ""; 8585 } ); 8586 } 8587 8588 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 8589 8590 // If set returns undefined, fall back to normal setting 8591 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 8592 this.value = val; 8593 } 8594 } ); 8595 } 8596} ); 8597 8598jQuery.extend( { 8599 valHooks: { 8600 option: { 8601 get: function( elem ) { 8602 8603 var val = jQuery.find.attr( elem, "value" ); 8604 return val != null ? 8605 val : 8606 8607 // Support: IE <=10 - 11 only 8608 // option.text throws exceptions (#14686, #14858) 8609 // Strip and collapse whitespace 8610 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8611 stripAndCollapse( jQuery.text( elem ) ); 8612 } 8613 }, 8614 select: { 8615 get: function( elem ) { 8616 var value, option, i, 8617 options = elem.options, 8618 index = elem.selectedIndex, 8619 one = elem.type === "select-one", 8620 values = one ? null : [], 8621 max = one ? index + 1 : options.length; 8622 8623 if ( index < 0 ) { 8624 i = max; 8625 8626 } else { 8627 i = one ? index : 0; 8628 } 8629 8630 // Loop through all the selected options 8631 for ( ; i < max; i++ ) { 8632 option = options[ i ]; 8633 8634 // Support: IE <=9 only 8635 // IE8-9 doesn't update selected after form reset (#2551) 8636 if ( ( option.selected || i === index ) && 8637 8638 // Don't return options that are disabled or in a disabled optgroup 8639 !option.disabled && 8640 ( !option.parentNode.disabled || 8641 !nodeName( option.parentNode, "optgroup" ) ) ) { 8642 8643 // Get the specific value for the option 8644 value = jQuery( option ).val(); 8645 8646 // We don't need an array for one selects 8647 if ( one ) { 8648 return value; 8649 } 8650 8651 // Multi-Selects return an array 8652 values.push( value ); 8653 } 8654 } 8655 8656 return values; 8657 }, 8658 8659 set: function( elem, value ) { 8660 var optionSet, option, 8661 options = elem.options, 8662 values = jQuery.makeArray( value ), 8663 i = options.length; 8664 8665 while ( i-- ) { 8666 option = options[ i ]; 8667 8668 /* eslint-disable no-cond-assign */ 8669 8670 if ( option.selected = 8671 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 8672 ) { 8673 optionSet = true; 8674 } 8675 8676 /* eslint-enable no-cond-assign */ 8677 } 8678 8679 // Force browsers to behave consistently when non-matching value is set 8680 if ( !optionSet ) { 8681 elem.selectedIndex = -1; 8682 } 8683 return values; 8684 } 8685 } 8686 } 8687} ); 8688 8689// Radios and checkboxes getter/setter 8690jQuery.each( [ "radio", "checkbox" ], function() { 8691 jQuery.valHooks[ this ] = { 8692 set: function( elem, value ) { 8693 if ( Array.isArray( value ) ) { 8694 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 8695 } 8696 } 8697 }; 8698 if ( !support.checkOn ) { 8699 jQuery.valHooks[ this ].get = function( elem ) { 8700 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 8701 }; 8702 } 8703} ); 8704 8705 8706 8707 8708// Return jQuery for attributes-only inclusion 8709 8710 8711support.focusin = "onfocusin" in window; 8712 8713 8714var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 8715 stopPropagationCallback = function( e ) { 8716 e.stopPropagation(); 8717 }; 8718 8719jQuery.extend( jQuery.event, { 8720 8721 trigger: function( event, data, elem, onlyHandlers ) { 8722 8723 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 8724 eventPath = [ elem || document ], 8725 type = hasOwn.call( event, "type" ) ? event.type : event, 8726 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 8727 8728 cur = lastElement = tmp = elem = elem || document; 8729 8730 // Don't do events on text and comment nodes 8731 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 8732 return; 8733 } 8734 8735 // focus/blur morphs to focusin/out; ensure we're not firing them right now 8736 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 8737 return; 8738 } 8739 8740 if ( type.indexOf( "." ) > -1 ) { 8741 8742 // Namespaced trigger; create a regexp to match event type in handle() 8743 namespaces = type.split( "." ); 8744 type = namespaces.shift(); 8745 namespaces.sort(); 8746 } 8747 ontype = type.indexOf( ":" ) < 0 && "on" + type; 8748 8749 // Caller can pass in a jQuery.Event object, Object, or just an event type string 8750 event = event[ jQuery.expando ] ? 8751 event : 8752 new jQuery.Event( type, typeof event === "object" && event ); 8753 8754 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 8755 event.isTrigger = onlyHandlers ? 2 : 3; 8756 event.namespace = namespaces.join( "." ); 8757 event.rnamespace = event.namespace ? 8758 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 8759 null; 8760 8761 // Clean up the event in case it is being reused 8762 event.result = undefined; 8763 if ( !event.target ) { 8764 event.target = elem; 8765 } 8766 8767 // Clone any incoming data and prepend the event, creating the handler arg list 8768 data = data == null ? 8769 [ event ] : 8770 jQuery.makeArray( data, [ event ] ); 8771 8772 // Allow special events to draw outside the lines 8773 special = jQuery.event.special[ type ] || {}; 8774 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 8775 return; 8776 } 8777 8778 // Determine event propagation path in advance, per W3C events spec (#9951) 8779 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 8780 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 8781 8782 bubbleType = special.delegateType || type; 8783 if ( !rfocusMorph.test( bubbleType + type ) ) { 8784 cur = cur.parentNode; 8785 } 8786 for ( ; cur; cur = cur.parentNode ) { 8787 eventPath.push( cur ); 8788 tmp = cur; 8789 } 8790 8791 // Only add window if we got to document (e.g., not plain obj or detached DOM) 8792 if ( tmp === ( elem.ownerDocument || document ) ) { 8793 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 8794 } 8795 } 8796 8797 // Fire handlers on the event path 8798 i = 0; 8799 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 8800 lastElement = cur; 8801 event.type = i > 1 ? 8802 bubbleType : 8803 special.bindType || type; 8804 8805 // jQuery handler 8806 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 8807 dataPriv.get( cur, "handle" ); 8808 if ( handle ) { 8809 handle.apply( cur, data ); 8810 } 8811 8812 // Native handler 8813 handle = ontype && cur[ ontype ]; 8814 if ( handle && handle.apply && acceptData( cur ) ) { 8815 event.result = handle.apply( cur, data ); 8816 if ( event.result === false ) { 8817 event.preventDefault(); 8818 } 8819 } 8820 } 8821 event.type = type; 8822 8823 // If nobody prevented the default action, do it now 8824 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 8825 8826 if ( ( !special._default || 8827 special._default.apply( eventPath.pop(), data ) === false ) && 8828 acceptData( elem ) ) { 8829 8830 // Call a native DOM method on the target with the same name as the event. 8831 // Don't do default actions on window, that's where global variables be (#6170) 8832 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 8833 8834 // Don't re-trigger an onFOO event when we call its FOO() method 8835 tmp = elem[ ontype ]; 8836 8837 if ( tmp ) { 8838 elem[ ontype ] = null; 8839 } 8840 8841 // Prevent re-triggering of the same event, since we already bubbled it above 8842 jQuery.event.triggered = type; 8843 8844 if ( event.isPropagationStopped() ) { 8845 lastElement.addEventListener( type, stopPropagationCallback ); 8846 } 8847 8848 elem[ type ](); 8849 8850 if ( event.isPropagationStopped() ) { 8851 lastElement.removeEventListener( type, stopPropagationCallback ); 8852 } 8853 8854 jQuery.event.triggered = undefined; 8855 8856 if ( tmp ) { 8857 elem[ ontype ] = tmp; 8858 } 8859 } 8860 } 8861 } 8862 8863 return event.result; 8864 }, 8865 8866 // Piggyback on a donor event to simulate a different one 8867 // Used only for `focus(in | out)` events 8868 simulate: function( type, elem, event ) { 8869 var e = jQuery.extend( 8870 new jQuery.Event(), 8871 event, 8872 { 8873 type: type, 8874 isSimulated: true 8875 } 8876 ); 8877 8878 jQuery.event.trigger( e, null, elem ); 8879 } 8880 8881} ); 8882 8883jQuery.fn.extend( { 8884 8885 trigger: function( type, data ) { 8886 return this.each( function() { 8887 jQuery.event.trigger( type, data, this ); 8888 } ); 8889 }, 8890 triggerHandler: function( type, data ) { 8891 var elem = this[ 0 ]; 8892 if ( elem ) { 8893 return jQuery.event.trigger( type, data, elem, true ); 8894 } 8895 } 8896} ); 8897 8898 8899// Support: Firefox <=44 8900// Firefox doesn't have focus(in | out) events 8901// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 8902// 8903// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 8904// focus(in | out) events fire after focus & blur events, 8905// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
vendor: 53,617 bytes, lines 8906-10931
8906// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 8907if ( !support.focusin ) { 8908 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 8909 8910 // Attach a single capturing handler on the document while someone wants focusin/focusout 8911 var handler = function( event ) { 8912 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 8913 }; 8914 8915 jQuery.event.special[ fix ] = { 8916 setup: function() { 8917 8918 // Handle: regular nodes (via `this.ownerDocument`), window 8919 // (via `this.document`) & document (via `this`). 8920 var doc = this.ownerDocument || this.document || this, 8921 attaches = dataPriv.access( doc, fix ); 8922 8923 if ( !attaches ) { 8924 doc.addEventListener( orig, handler, true ); 8925 } 8926 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 8927 }, 8928 teardown: function() { 8929 var doc = this.ownerDocument || this.document || this, 8930 attaches = dataPriv.access( doc, fix ) - 1; 8931 8932 if ( !attaches ) { 8933 doc.removeEventListener( orig, handler, true ); 8934 dataPriv.remove( doc, fix ); 8935 8936 } else { 8937 dataPriv.access( doc, fix, attaches ); 8938 } 8939 } 8940 }; 8941 } ); 8942} 8943var location = window.location; 8944 8945var nonce = { guid: Date.now() }; 8946 8947var rquery = ( /\?/ ); 8948 8949 8950 8951// Cross-browser xml parsing 8952jQuery.parseXML = function( data ) { 8953 var xml, parserErrorElem; 8954 if ( !data || typeof data !== "string" ) { 8955 return null; 8956 } 8957 8958 // Support: IE 9 - 11 only 8959 // IE throws on parseFromString with invalid input. 8960 try { 8961 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 8962 } catch ( e ) {} 8963 8964 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 8965 if ( !xml || parserErrorElem ) { 8966 jQuery.error( "Invalid XML: " + ( 8967 parserErrorElem ? 8968 jQuery.map( parserErrorElem.childNodes, function( el ) { 8969 return el.textContent; 8970 } ).join( "\n" ) : 8971 data 8972 ) ); 8973 } 8974 return xml; 8975}; 8976 8977 8978var 8979 rbracket = /\[\]$/, 8980 rCRLF = /\r?\n/g, 8981 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8982 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8983 8984function buildParams( prefix, obj, traditional, add ) { 8985 var name; 8986 8987 if ( Array.isArray( obj ) ) { 8988 8989 // Serialize array item. 8990 jQuery.each( obj, function( i, v ) { 8991 if ( traditional || rbracket.test( prefix ) ) { 8992 8993 // Treat each array item as a scalar. 8994 add( prefix, v ); 8995 8996 } else { 8997 8998 // Item is non-scalar (array or object), encode its numeric index. 8999 buildParams( 9000 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 9001 v, 9002 traditional, 9003 add 9004 ); 9005 } 9006 } ); 9007 9008 } else if ( !traditional && toType( obj ) === "object" ) { 9009 9010 // Serialize object item. 9011 for ( name in obj ) { 9012 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 9013 } 9014 9015 } else { 9016 9017 // Serialize scalar item. 9018 add( prefix, obj ); 9019 } 9020} 9021 9022// Serialize an array of form elements or a set of 9023// key/values into a query string 9024jQuery.param = function( a, traditional ) { 9025 var prefix, 9026 s = [], 9027 add = function( key, valueOrFunction ) { 9028 9029 // If value is a function, invoke it and use its return value 9030 var value = isFunction( valueOrFunction ) ? 9031 valueOrFunction() : 9032 valueOrFunction; 9033 9034 s[ s.length ] = encodeURIComponent( key ) + "=" + 9035 encodeURIComponent( value == null ? "" : value ); 9036 }; 9037 9038 if ( a == null ) { 9039 return ""; 9040 } 9041 9042 // If an array was passed in, assume that it is an array of form elements. 9043 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 9044 9045 // Serialize the form elements 9046 jQuery.each( a, function() { 9047 add( this.name, this.value ); 9048 } ); 9049 9050 } else { 9051 9052 // If traditional, encode the "old" way (the way 1.3.2 or older 9053 // did it), otherwise encode params recursively. 9054 for ( prefix in a ) { 9055 buildParams( prefix, a[ prefix ], traditional, add ); 9056 } 9057 } 9058 9059 // Return the resulting serialization 9060 return s.join( "&" ); 9061}; 9062 9063jQuery.fn.extend( { 9064 serialize: function() { 9065 return jQuery.param( this.serializeArray() ); 9066 }, 9067 serializeArray: function() { 9068 return this.map( function() { 9069 9070 // Can add propHook for "elements" to filter or add form elements 9071 var elements = jQuery.prop( this, "elements" ); 9072 return elements ? jQuery.makeArray( elements ) : this; 9073 } ).filter( function() { 9074 var type = this.type; 9075 9076 // Use .is( ":disabled" ) so that fieldset[disabled] works 9077 return this.name && !jQuery( this ).is( ":disabled" ) && 9078 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 9079 ( this.checked || !rcheckableType.test( type ) ); 9080 } ).map( function( _i, elem ) { 9081 var val = jQuery( this ).val(); 9082 9083 if ( val == null ) { 9084 return null; 9085 } 9086 9087 if ( Array.isArray( val ) ) { 9088 return jQuery.map( val, function( val ) { 9089 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 9090 } ); 9091 } 9092 9093 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 9094 } ).get(); 9095 } 9096} ); 9097 9098 9099var 9100 r20 = /%20/g, 9101 rhash = /#.*$/, 9102 rantiCache = /([?&])_=[^&]*/, 9103 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 9104 9105 // #7653, #8125, #8152: local protocol detection 9106 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 9107 rnoContent = /^(?:GET|HEAD)$/, 9108 rprotocol = /^\/\//, 9109 9110 /* Prefilters 9111 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 9112 * 2) These are called: 9113 * - BEFORE asking for a transport 9114 * - AFTER param serialization (s.data is a string if s.processData is true) 9115 * 3) key is the dataType 9116 * 4) the catchall symbol "*" can be used 9117 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 9118 */ 9119 prefilters = {}, 9120 9121 /* Transports bindings 9122 * 1) key is the dataType 9123 * 2) the catchall symbol "*" can be used 9124 * 3) selection will start with transport dataType and THEN go to "*" if needed 9125 */ 9126 transports = {}, 9127 9128 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 9129 allTypes = "*/".concat( "*" ), 9130 9131 // Anchor tag for parsing the document origin 9132 originAnchor = document.createElement( "a" ); 9133 9134originAnchor.href = location.href; 9135 9136// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 9137function addToPrefiltersOrTransports( structure ) { 9138 9139 // dataTypeExpression is optional and defaults to "*" 9140 return function( dataTypeExpression, func ) { 9141 9142 if ( typeof dataTypeExpression !== "string" ) { 9143 func = dataTypeExpression; 9144 dataTypeExpression = "*"; 9145 } 9146 9147 var dataType, 9148 i = 0, 9149 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 9150 9151 if ( isFunction( func ) ) { 9152 9153 // For each dataType in the dataTypeExpression 9154 while ( ( dataType = dataTypes[ i++ ] ) ) { 9155 9156 // Prepend if requested 9157 if ( dataType[ 0 ] === "+" ) { 9158 dataType = dataType.slice( 1 ) || "*"; 9159 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 9160 9161 // Otherwise append 9162 } else { 9163 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 9164 } 9165 } 9166 } 9167 }; 9168} 9169 9170// Base inspection function for prefilters and transports 9171function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 9172 9173 var inspected = {}, 9174 seekingTransport = ( structure === transports ); 9175 9176 function inspect( dataType ) { 9177 var selected; 9178 inspected[ dataType ] = true; 9179 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 9180 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 9181 if ( typeof dataTypeOrTransport === "string" && 9182 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 9183 9184 options.dataTypes.unshift( dataTypeOrTransport ); 9185 inspect( dataTypeOrTransport ); 9186 return false; 9187 } else if ( seekingTransport ) { 9188 return !( selected = dataTypeOrTransport ); 9189 } 9190 } ); 9191 return selected; 9192 } 9193 9194 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 9195} 9196 9197// A special extend for ajax options 9198// that takes "flat" options (not to be deep extended) 9199// Fixes #9887 9200function ajaxExtend( target, src ) { 9201 var key, deep, 9202 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 9203 9204 for ( key in src ) { 9205 if ( src[ key ] !== undefined ) { 9206 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 9207 } 9208 } 9209 if ( deep ) { 9210 jQuery.extend( true, target, deep ); 9211 } 9212 9213 return target; 9214} 9215 9216/* Handles responses to an ajax request: 9217 * - finds the right dataType (mediates between content-type and expected dataType) 9218 * - returns the corresponding response 9219 */ 9220function ajaxHandleResponses( s, jqXHR, responses ) { 9221 9222 var ct, type, finalDataType, firstDataType, 9223 contents = s.contents, 9224 dataTypes = s.dataTypes; 9225 9226 // Remove auto dataType and get content-type in the process 9227 while ( dataTypes[ 0 ] === "*" ) { 9228 dataTypes.shift(); 9229 if ( ct === undefined ) { 9230 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 9231 } 9232 } 9233 9234 // Check if we're dealing with a known content-type 9235 if ( ct ) { 9236 for ( type in contents ) { 9237 if ( contents[ type ] && contents[ type ].test( ct ) ) { 9238 dataTypes.unshift( type ); 9239 break; 9240 } 9241 } 9242 } 9243 9244 // Check to see if we have a response for the expected dataType 9245 if ( dataTypes[ 0 ] in responses ) { 9246 finalDataType = dataTypes[ 0 ]; 9247 } else { 9248 9249 // Try convertible dataTypes 9250 for ( type in responses ) { 9251 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 9252 finalDataType = type; 9253 break; 9254 } 9255 if ( !firstDataType ) { 9256 firstDataType = type; 9257 } 9258 } 9259 9260 // Or just use first one 9261 finalDataType = finalDataType || firstDataType; 9262 } 9263 9264 // If we found a dataType 9265 // We add the dataType to the list if needed 9266 // and return the corresponding response 9267 if ( finalDataType ) { 9268 if ( finalDataType !== dataTypes[ 0 ] ) { 9269 dataTypes.unshift( finalDataType ); 9270 } 9271 return responses[ finalDataType ]; 9272 } 9273} 9274 9275/* Chain conversions given the request and the original response 9276 * Also sets the responseXXX fields on the jqXHR instance 9277 */ 9278function ajaxConvert( s, response, jqXHR, isSuccess ) { 9279 var conv2, current, conv, tmp, prev, 9280 converters = {}, 9281 9282 // Work with a copy of dataTypes in case we need to modify it for conversion 9283 dataTypes = s.dataTypes.slice(); 9284 9285 // Create converters map with lowercased keys 9286 if ( dataTypes[ 1 ] ) { 9287 for ( conv in s.converters ) { 9288 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 9289 } 9290 } 9291 9292 current = dataTypes.shift(); 9293 9294 // Convert to each sequential dataType 9295 while ( current ) { 9296 9297 if ( s.responseFields[ current ] ) { 9298 jqXHR[ s.responseFields[ current ] ] = response; 9299 } 9300 9301 // Apply the dataFilter if provided 9302 if ( !prev && isSuccess && s.dataFilter ) { 9303 response = s.dataFilter( response, s.dataType ); 9304 } 9305 9306 prev = current; 9307 current = dataTypes.shift(); 9308 9309 if ( current ) { 9310 9311 // There's only work to do if current dataType is non-auto 9312 if ( current === "*" ) { 9313 9314 current = prev; 9315 9316 // Convert response if prev dataType is non-auto and differs from current 9317 } else if ( prev !== "*" && prev !== current ) { 9318 9319 // Seek a direct converter 9320 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 9321 9322 // If none found, seek a pair 9323 if ( !conv ) { 9324 for ( conv2 in converters ) { 9325 9326 // If conv2 outputs current 9327 tmp = conv2.split( " " ); 9328 if ( tmp[ 1 ] === current ) { 9329 9330 // If prev can be converted to accepted input 9331 conv = converters[ prev + " " + tmp[ 0 ] ] || 9332 converters[ "* " + tmp[ 0 ] ]; 9333 if ( conv ) { 9334 9335 // Condense equivalence converters 9336 if ( conv === true ) { 9337 conv = converters[ conv2 ]; 9338 9339 // Otherwise, insert the intermediate dataType 9340 } else if ( converters[ conv2 ] !== true ) { 9341 current = tmp[ 0 ]; 9342 dataTypes.unshift( tmp[ 1 ] ); 9343 } 9344 break; 9345 } 9346 } 9347 } 9348 } 9349 9350 // Apply converter (if not an equivalence) 9351 if ( conv !== true ) { 9352 9353 // Unless errors are allowed to bubble, catch and return them 9354 if ( conv && s.throws ) { 9355 response = conv( response ); 9356 } else { 9357 try { 9358 response = conv( response ); 9359 } catch ( e ) { 9360 return { 9361 state: "parsererror", 9362 error: conv ? e : "No conversion from " + prev + " to " + current 9363 }; 9364 } 9365 } 9366 } 9367 } 9368 } 9369 } 9370 9371 return { state: "success", data: response }; 9372} 9373 9374jQuery.extend( { 9375 9376 // Counter for holding the number of active queries 9377 active: 0, 9378 9379 // Last-Modified header cache for next request 9380 lastModified: {}, 9381 etag: {}, 9382 9383 ajaxSettings: { 9384 url: location.href, 9385 type: "GET", 9386 isLocal: rlocalProtocol.test( location.protocol ), 9387 global: true, 9388 processData: true, 9389 async: true, 9390 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9391 9392 /* 9393 timeout: 0, 9394 data: null, 9395 dataType: null, 9396 username: null, 9397 password: null, 9398 cache: null, 9399 throws: false, 9400 traditional: false, 9401 headers: {}, 9402 */ 9403 9404 accepts: { 9405 "*": allTypes, 9406 text: "text/plain", 9407 html: "text/html", 9408 xml: "application/xml, text/xml", 9409 json: "application/json, text/javascript" 9410 }, 9411 9412 contents: { 9413 xml: /\bxml\b/, 9414 html: /\bhtml/, 9415 json: /\bjson\b/ 9416 }, 9417 9418 responseFields: { 9419 xml: "responseXML", 9420 text: "responseText", 9421 json: "responseJSON" 9422 }, 9423 9424 // Data converters 9425 // Keys separate source (or catchall "*") and destination types with a single space 9426 converters: { 9427 9428 // Convert anything to text 9429 "* text": String, 9430 9431 // Text to html (true = no transformation) 9432 "text html": true, 9433 9434 // Evaluate text as a json expression 9435 "text json": JSON.parse, 9436 9437 // Parse text as xml 9438 "text xml": jQuery.parseXML 9439 }, 9440 9441 // For options that shouldn't be deep extended: 9442 // you can add your own custom options here if 9443 // and when you create one that shouldn't be 9444 // deep extended (see ajaxExtend) 9445 flatOptions: { 9446 url: true, 9447 context: true 9448 } 9449 }, 9450 9451 // Creates a full fledged settings object into target 9452 // with both ajaxSettings and settings fields. 9453 // If target is omitted, writes into ajaxSettings. 9454 ajaxSetup: function( target, settings ) { 9455 return settings ? 9456 9457 // Building a settings object 9458 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 9459 9460 // Extending ajaxSettings 9461 ajaxExtend( jQuery.ajaxSettings, target ); 9462 }, 9463 9464 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 9465 ajaxTransport: addToPrefiltersOrTransports( transports ), 9466 9467 // Main method 9468 ajax: function( url, options ) { 9469 9470 // If url is an object, simulate pre-1.5 signature 9471 if ( typeof url === "object" ) { 9472 options = url; 9473 url = undefined; 9474 } 9475 9476 // Force options to be an object 9477 options = options || {}; 9478 9479 var transport, 9480 9481 // URL without anti-cache param 9482 cacheURL, 9483 9484 // Response headers 9485 responseHeadersString, 9486 responseHeaders, 9487 9488 // timeout handle 9489 timeoutTimer, 9490 9491 // Url cleanup var 9492 urlAnchor, 9493 9494 // Request state (becomes false upon send and true upon completion) 9495 completed, 9496 9497 // To know if global events are to be dispatched 9498 fireGlobals, 9499 9500 // Loop variable 9501 i, 9502 9503 // uncached part of the url 9504 uncached, 9505 9506 // Create the final options object 9507 s = jQuery.ajaxSetup( {}, options ), 9508 9509 // Callbacks context 9510 callbackContext = s.context || s, 9511 9512 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9513 globalEventContext = s.context && 9514 ( callbackContext.nodeType || callbackContext.jquery ) ? 9515 jQuery( callbackContext ) : 9516 jQuery.event, 9517 9518 // Deferreds 9519 deferred = jQuery.Deferred(), 9520 completeDeferred = jQuery.Callbacks( "once memory" ), 9521 9522 // Status-dependent callbacks 9523 statusCode = s.statusCode || {}, 9524 9525 // Headers (they are sent all at once) 9526 requestHeaders = {}, 9527 requestHeadersNames = {}, 9528 9529 // Default abort message 9530 strAbort = "canceled", 9531 9532 // Fake xhr 9533 jqXHR = { 9534 readyState: 0, 9535 9536 // Builds headers hashtable if needed 9537 getResponseHeader: function( key ) { 9538 var match; 9539 if ( completed ) { 9540 if ( !responseHeaders ) { 9541 responseHeaders = {}; 9542 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 9543 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 9544 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 9545 .concat( match[ 2 ] ); 9546 } 9547 } 9548 match = responseHeaders[ key.toLowerCase() + " " ]; 9549 } 9550 return match == null ? null : match.join( ", " ); 9551 }, 9552 9553 // Raw string 9554 getAllResponseHeaders: function() { 9555 return completed ? responseHeadersString : null; 9556 }, 9557 9558 // Caches the header 9559 setRequestHeader: function( name, value ) { 9560 if ( completed == null ) { 9561 name = requestHeadersNames[ name.toLowerCase() ] = 9562 requestHeadersNames[ name.toLowerCase() ] || name; 9563 requestHeaders[ name ] = value; 9564 } 9565 return this; 9566 }, 9567 9568 // Overrides response content-type header 9569 overrideMimeType: function( type ) { 9570 if ( completed == null ) { 9571 s.mimeType = type; 9572 } 9573 return this; 9574 }, 9575 9576 // Status-dependent callbacks 9577 statusCode: function( map ) { 9578 var code; 9579 if ( map ) { 9580 if ( completed ) { 9581 9582 // Execute the appropriate callbacks 9583 jqXHR.always( map[ jqXHR.status ] ); 9584 } else { 9585 9586 // Lazy-add the new callbacks in a way that preserves old ones 9587 for ( code in map ) { 9588 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 9589 } 9590 } 9591 } 9592 return this; 9593 }, 9594 9595 // Cancel the request 9596 abort: function( statusText ) { 9597 var finalText = statusText || strAbort; 9598 if ( transport ) { 9599 transport.abort( finalText ); 9600 } 9601 done( 0, finalText ); 9602 return this; 9603 } 9604 }; 9605 9606 // Attach deferreds 9607 deferred.promise( jqXHR ); 9608 9609 // Add protocol if not provided (prefilters might expect it) 9610 // Handle falsy url in the settings object (#10093: consistency with old signature) 9611 // We also use the url parameter if available 9612 s.url = ( ( url || s.url || location.href ) + "" ) 9613 .replace( rprotocol, location.protocol + "//" ); 9614 9615 // Alias method option to type as per ticket #12004 9616 s.type = options.method || options.type || s.method || s.type; 9617 9618 // Extract dataTypes list 9619 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 9620 9621 // A cross-domain request is in order when the origin doesn't match the current origin. 9622 if ( s.crossDomain == null ) { 9623 urlAnchor = document.createElement( "a" ); 9624 9625 // Support: IE <=8 - 11, Edge 12 - 15 9626 // IE throws exception on accessing the href property if url is malformed, 9627 // e.g. http://example.com:80x/ 9628 try { 9629 urlAnchor.href = s.url; 9630 9631 // Support: IE <=8 - 11 only 9632 // Anchor's host property isn't correctly set when s.url is relative 9633 urlAnchor.href = urlAnchor.href; 9634 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 9635 urlAnchor.protocol + "//" + urlAnchor.host; 9636 } catch ( e ) { 9637 9638 // If there is an error parsing the URL, assume it is crossDomain, 9639 // it can be rejected by the transport if it is invalid 9640 s.crossDomain = true; 9641 } 9642 } 9643 9644 // Convert data if not already a string 9645 if ( s.data && s.processData && typeof s.data !== "string" ) { 9646 s.data = jQuery.param( s.data, s.traditional ); 9647 } 9648 9649 // Apply prefilters 9650 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 9651 9652 // If request was aborted inside a prefilter, stop there 9653 if ( completed ) { 9654 return jqXHR; 9655 } 9656 9657 // We can fire global events as of now if asked to 9658 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 9659 fireGlobals = jQuery.event && s.global; 9660 9661 // Watch for a new set of requests 9662 if ( fireGlobals && jQuery.active++ === 0 ) { 9663 jQuery.event.trigger( "ajaxStart" ); 9664 } 9665 9666 // Uppercase the type 9667 s.type = s.type.toUpperCase(); 9668 9669 // Determine if request has content 9670 s.hasContent = !rnoContent.test( s.type ); 9671 9672 // Save the URL in case we're toying with the If-Modified-Since 9673 // and/or If-None-Match header later on 9674 // Remove hash to simplify url manipulation 9675 cacheURL = s.url.replace( rhash, "" ); 9676 9677 // More options handling for requests with no content 9678 if ( !s.hasContent ) { 9679 9680 // Remember the hash so we can put it back 9681 uncached = s.url.slice( cacheURL.length ); 9682 9683 // If data is available and should be processed, append data to url 9684 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 9685 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 9686 9687 // #9682: remove data so that it's not used in an eventual retry 9688 delete s.data; 9689 } 9690 9691 // Add or update anti-cache param if needed 9692 if ( s.cache === false ) { 9693 cacheURL = cacheURL.replace( rantiCache, "$1" ); 9694 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 9695 uncached; 9696 } 9697 9698 // Put hash and anti-cache on the URL that will be requested (gh-1732) 9699 s.url = cacheURL + uncached; 9700 9701 // Change '%20' to '+' if this is encoded form body content (gh-2658) 9702 } else if ( s.data && s.processData && 9703 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 9704 s.data = s.data.replace( r20, "+" ); 9705 } 9706 9707 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9708 if ( s.ifModified ) { 9709 if ( jQuery.lastModified[ cacheURL ] ) { 9710 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 9711 } 9712 if ( jQuery.etag[ cacheURL ] ) { 9713 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 9714 } 9715 } 9716 9717 // Set the correct header, if data is being sent 9718 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 9719 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 9720 } 9721 9722 // Set the Accepts header for the server, depending on the dataType 9723 jqXHR.setRequestHeader( 9724 "Accept", 9725 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 9726 s.accepts[ s.dataTypes[ 0 ] ] + 9727 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 9728 s.accepts[ "*" ] 9729 ); 9730 9731 // Check for headers option 9732 for ( i in s.headers ) { 9733 jqXHR.setRequestHeader( i, s.headers[ i ] ); 9734 } 9735 9736 // Allow custom headers/mimetypes and early abort 9737 if ( s.beforeSend && 9738 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 9739 9740 // Abort if not done already and return 9741 return jqXHR.abort(); 9742 } 9743 9744 // Aborting is no longer a cancellation 9745 strAbort = "abort"; 9746 9747 // Install callbacks on deferreds 9748 completeDeferred.add( s.complete ); 9749 jqXHR.done( s.success ); 9750 jqXHR.fail( s.error ); 9751 9752 // Get transport 9753 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 9754 9755 // If no transport, we auto-abort 9756 if ( !transport ) { 9757 done( -1, "No Transport" ); 9758 } else { 9759 jqXHR.readyState = 1; 9760 9761 // Send global event 9762 if ( fireGlobals ) { 9763 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 9764 } 9765 9766 // If request was aborted inside ajaxSend, stop there 9767 if ( completed ) { 9768 return jqXHR; 9769 } 9770 9771 // Timeout 9772 if ( s.async && s.timeout > 0 ) { 9773 timeoutTimer = window.setTimeout( function() { 9774 jqXHR.abort( "timeout" ); 9775 }, s.timeout ); 9776 } 9777 9778 try { 9779 completed = false; 9780 transport.send( requestHeaders, done ); 9781 } catch ( e ) { 9782 9783 // Rethrow post-completion exceptions 9784 if ( completed ) { 9785 throw e; 9786 } 9787 9788 // Propagate others as results 9789 done( -1, e ); 9790 } 9791 } 9792 9793 // Callback for when everything is done 9794 function done( status, nativeStatusText, responses, headers ) { 9795 var isSuccess, success, error, response, modified, 9796 statusText = nativeStatusText; 9797 9798 // Ignore repeat invocations 9799 if ( completed ) { 9800 return; 9801 } 9802 9803 completed = true; 9804 9805 // Clear timeout if it exists 9806 if ( timeoutTimer ) { 9807 window.clearTimeout( timeoutTimer ); 9808 } 9809 9810 // Dereference transport for early garbage collection 9811 // (no matter how long the jqXHR object will be used) 9812 transport = undefined; 9813 9814 // Cache response headers 9815 responseHeadersString = headers || ""; 9816 9817 // Set readyState 9818 jqXHR.readyState = status > 0 ? 4 : 0; 9819 9820 // Determine if successful 9821 isSuccess = status >= 200 && status < 300 || status === 304; 9822 9823 // Get response data 9824 if ( responses ) { 9825 response = ajaxHandleResponses( s, jqXHR, responses ); 9826 } 9827 9828 // Use a noop converter for missing script but not if jsonp 9829 if ( !isSuccess && 9830 jQuery.inArray( "script", s.dataTypes ) > -1 && 9831 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 9832 s.converters[ "text script" ] = function() {}; 9833 } 9834 9835 // Convert no matter what (that way responseXXX fields are always set) 9836 response = ajaxConvert( s, response, jqXHR, isSuccess ); 9837 9838 // If successful, handle type chaining 9839 if ( isSuccess ) { 9840 9841 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9842 if ( s.ifModified ) { 9843 modified = jqXHR.getResponseHeader( "Last-Modified" ); 9844 if ( modified ) { 9845 jQuery.lastModified[ cacheURL ] = modified; 9846 } 9847 modified = jqXHR.getResponseHeader( "etag" ); 9848 if ( modified ) { 9849 jQuery.etag[ cacheURL ] = modified; 9850 } 9851 } 9852 9853 // if no content 9854 if ( status === 204 || s.type === "HEAD" ) { 9855 statusText = "nocontent"; 9856 9857 // if not modified 9858 } else if ( status === 304 ) { 9859 statusText = "notmodified"; 9860 9861 // If we have data, let's convert it 9862 } else { 9863 statusText = response.state; 9864 success = response.data; 9865 error = response.error; 9866 isSuccess = !error; 9867 } 9868 } else { 9869 9870 // Extract error from statusText and normalize for non-aborts 9871 error = statusText; 9872 if ( status || !statusText ) { 9873 statusText = "error"; 9874 if ( status < 0 ) { 9875 status = 0; 9876 } 9877 } 9878 } 9879 9880 // Set data for the fake xhr object 9881 jqXHR.status = status; 9882 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 9883 9884 // Success/Error 9885 if ( isSuccess ) { 9886 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 9887 } else { 9888 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 9889 } 9890 9891 // Status-dependent callbacks 9892 jqXHR.statusCode( statusCode ); 9893 statusCode = undefined; 9894 9895 if ( fireGlobals ) { 9896 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 9897 [ jqXHR, s, isSuccess ? success : error ] ); 9898 } 9899 9900 // Complete 9901 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 9902 9903 if ( fireGlobals ) { 9904 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 9905 9906 // Handle the global AJAX counter 9907 if ( !( --jQuery.active ) ) { 9908 jQuery.event.trigger( "ajaxStop" ); 9909 } 9910 } 9911 } 9912 9913 return jqXHR; 9914 }, 9915 9916 getJSON: function( url, data, callback ) { 9917 return jQuery.get( url, data, callback, "json" ); 9918 }, 9919 9920 getScript: function( url, callback ) { 9921 return jQuery.get( url, undefined, callback, "script" ); 9922 } 9923} ); 9924 9925jQuery.each( [ "get", "post" ], function( _i, method ) { 9926 jQuery[ method ] = function( url, data, callback, type ) { 9927 9928 // Shift arguments if data argument was omitted 9929 if ( isFunction( data ) ) { 9930 type = type || callback; 9931 callback = data; 9932 data = undefined; 9933 } 9934 9935 // The url can be an options object (which then must have .url) 9936 return jQuery.ajax( jQuery.extend( { 9937 url: url, 9938 type: method, 9939 dataType: type, 9940 data: data, 9941 success: callback 9942 }, jQuery.isPlainObject( url ) && url ) ); 9943 }; 9944} ); 9945 9946jQuery.ajaxPrefilter( function( s ) { 9947 var i; 9948 for ( i in s.headers ) { 9949 if ( i.toLowerCase() === "content-type" ) { 9950 s.contentType = s.headers[ i ] || ""; 9951 } 9952 } 9953} ); 9954 9955 9956jQuery._evalUrl = function( url, options, doc ) { 9957 return jQuery.ajax( { 9958 url: url, 9959 9960 // Make this explicit, since user can override this through ajaxSetup (#11264) 9961 type: "GET", 9962 dataType: "script", 9963 cache: true, 9964 async: false, 9965 global: false, 9966 9967 // Only evaluate the response if it is successful (gh-4126) 9968 // dataFilter is not invoked for failure responses, so using it instead 9969 // of the default converter is kludgy but it works. 9970 converters: { 9971 "text script": function() {} 9972 }, 9973 dataFilter: function( response ) { 9974 jQuery.globalEval( response, options, doc ); 9975 } 9976 } ); 9977}; 9978 9979 9980jQuery.fn.extend( { 9981 wrapAll: function( html ) { 9982 var wrap; 9983 9984 if ( this[ 0 ] ) { 9985 if ( isFunction( html ) ) { 9986 html = html.call( this[ 0 ] ); 9987 } 9988 9989 // The elements to wrap the target around 9990 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 9991 9992 if ( this[ 0 ].parentNode ) { 9993 wrap.insertBefore( this[ 0 ] ); 9994 } 9995 9996 wrap.map( function() { 9997 var elem = this; 9998 9999 while ( elem.firstElementChild ) { 10000 elem = elem.firstElementChild; 10001 } 10002 10003 return elem; 10004 } ).append( this ); 10005 } 10006 10007 return this; 10008 }, 10009 10010 wrapInner: function( html ) { 10011 if ( isFunction( html ) ) { 10012 return this.each( function( i ) { 10013 jQuery( this ).wrapInner( html.call( this, i ) ); 10014 } ); 10015 } 10016 10017 return this.each( function() { 10018 var self = jQuery( this ), 10019 contents = self.contents(); 10020 10021 if ( contents.length ) { 10022 contents.wrapAll( html ); 10023 10024 } else { 10025 self.append( html ); 10026 } 10027 } ); 10028 }, 10029 10030 wrap: function( html ) { 10031 var htmlIsFunction = isFunction( html ); 10032 10033 return this.each( function( i ) { 10034 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 10035 } ); 10036 }, 10037 10038 unwrap: function( selector ) { 10039 this.parent( selector ).not( "body" ).each( function() { 10040 jQuery( this ).replaceWith( this.childNodes ); 10041 } ); 10042 return this; 10043 } 10044} ); 10045 10046 10047jQuery.expr.pseudos.hidden = function( elem ) { 10048 return !jQuery.expr.pseudos.visible( elem ); 10049}; 10050jQuery.expr.pseudos.visible = function( elem ) { 10051 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 10052}; 10053 10054 10055 10056 10057jQuery.ajaxSettings.xhr = function() { 10058 try { 10059 return new window.XMLHttpRequest(); 10060 } catch ( e ) {} 10061}; 10062 10063var xhrSuccessStatus = { 10064 10065 // File protocol always yields status code 0, assume 200 10066 0: 200, 10067 10068 // Support: IE <=9 only 10069 // #1450: sometimes IE returns 1223 when it should be 204 10070 1223: 204 10071 }, 10072 xhrSupported = jQuery.ajaxSettings.xhr(); 10073 10074support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 10075support.ajax = xhrSupported = !!xhrSupported; 10076 10077jQuery.ajaxTransport( function( options ) { 10078 var callback, errorCallback; 10079 10080 // Cross domain only allowed if supported through XMLHttpRequest 10081 if ( support.cors || xhrSupported && !options.crossDomain ) { 10082 return { 10083 send: function( headers, complete ) { 10084 var i, 10085 xhr = options.xhr(); 10086 10087 xhr.open( 10088 options.type, 10089 options.url, 10090 options.async, 10091 options.username, 10092 options.password 10093 ); 10094 10095 // Apply custom fields if provided 10096 if ( options.xhrFields ) { 10097 for ( i in options.xhrFields ) { 10098 xhr[ i ] = options.xhrFields[ i ]; 10099 } 10100 } 10101 10102 // Override mime type if needed 10103 if ( options.mimeType && xhr.overrideMimeType ) { 10104 xhr.overrideMimeType( options.mimeType ); 10105 } 10106 10107 // X-Requested-With header 10108 // For cross-domain requests, seeing as conditions for a preflight are 10109 // akin to a jigsaw puzzle, we simply never set it to be sure. 10110 // (it can always be set on a per-request basis or even using ajaxSetup) 10111 // For same-domain requests, won't change header if already provided. 10112 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 10113 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 10114 } 10115 10116 // Set headers 10117 for ( i in headers ) { 10118 xhr.setRequestHeader( i, headers[ i ] ); 10119 } 10120 10121 // Callback 10122 callback = function( type ) { 10123 return function() { 10124 if ( callback ) { 10125 callback = errorCallback = xhr.onload = 10126 xhr.onerror = xhr.onabort = xhr.ontimeout = 10127 xhr.onreadystatechange = null; 10128 10129 if ( type === "abort" ) { 10130 xhr.abort(); 10131 } else if ( type === "error" ) { 10132 10133 // Support: IE <=9 only 10134 // On a manual native abort, IE9 throws 10135 // errors on any property access that is not readyState 10136 if ( typeof xhr.status !== "number" ) { 10137 complete( 0, "error" ); 10138 } else { 10139 complete( 10140 10141 // File: protocol always yields status 0; see #8605, #14207 10142 xhr.status, 10143 xhr.statusText 10144 ); 10145 } 10146 } else { 10147 complete( 10148 xhrSuccessStatus[ xhr.status ] || xhr.status, 10149 xhr.statusText, 10150 10151 // Support: IE <=9 only 10152 // IE9 has no XHR2 but throws on binary (trac-11426) 10153 // For XHR2 non-text, let the caller handle it (gh-2498) 10154 ( xhr.responseType || "text" ) !== "text" || 10155 typeof xhr.responseText !== "string" ? 10156 { binary: xhr.response } : 10157 { text: xhr.responseText }, 10158 xhr.getAllResponseHeaders() 10159 ); 10160 } 10161 } 10162 }; 10163 }; 10164 10165 // Listen to events 10166 xhr.onload = callback(); 10167 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 10168 10169 // Support: IE 9 only 10170 // Use onreadystatechange to replace onabort 10171 // to handle uncaught aborts 10172 if ( xhr.onabort !== undefined ) { 10173 xhr.onabort = errorCallback; 10174 } else { 10175 xhr.onreadystatechange = function() { 10176 10177 // Check readyState before timeout as it changes 10178 if ( xhr.readyState === 4 ) { 10179 10180 // Allow onerror to be called first, 10181 // but that will not handle a native abort 10182 // Also, save errorCallback to a variable 10183 // as xhr.onerror cannot be accessed 10184 window.setTimeout( function() { 10185 if ( callback ) { 10186 errorCallback(); 10187 } 10188 } ); 10189 } 10190 }; 10191 } 10192 10193 // Create the abort callback 10194 callback = callback( "abort" ); 10195 10196 try { 10197 10198 // Do send the request (this may raise an exception) 10199 xhr.send( options.hasContent && options.data || null ); 10200 } catch ( e ) { 10201 10202 // #14683: Only rethrow if this hasn't been notified as an error yet 10203 if ( callback ) { 10204 throw e; 10205 } 10206 } 10207 }, 10208 10209 abort: function() { 10210 if ( callback ) { 10211 callback(); 10212 } 10213 } 10214 }; 10215 } 10216} ); 10217 10218 10219 10220 10221// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 10222jQuery.ajaxPrefilter( function( s ) { 10223 if ( s.crossDomain ) { 10224 s.contents.script = false; 10225 } 10226} ); 10227 10228// Install script dataType 10229jQuery.ajaxSetup( { 10230 accepts: { 10231 script: "text/javascript, application/javascript, " + 10232 "application/ecmascript, application/x-ecmascript" 10233 }, 10234 contents: { 10235 script: /\b(?:java|ecma)script\b/ 10236 }, 10237 converters: { 10238 "text script": function( text ) { 10239 jQuery.globalEval( text ); 10240 return text; 10241 } 10242 } 10243} ); 10244 10245// Handle cache's special case and crossDomain 10246jQuery.ajaxPrefilter( "script", function( s ) { 10247 if ( s.cache === undefined ) { 10248 s.cache = false; 10249 } 10250 if ( s.crossDomain ) { 10251 s.type = "GET"; 10252 } 10253} ); 10254 10255// Bind script tag hack transport 10256jQuery.ajaxTransport( "script", function( s ) { 10257 10258 // This transport only deals with cross domain or forced-by-attrs requests 10259 if ( s.crossDomain || s.scriptAttrs ) { 10260 var script, callback; 10261 return { 10262 send: function( _, complete ) { 10263 script = jQuery( "<script>" ) 10264 .attr( s.scriptAttrs || {} ) 10265 .prop( { charset: s.scriptCharset, src: s.url } ) 10266 .on( "load error", callback = function( evt ) { 10267 script.remove(); 10268 callback = null; 10269 if ( evt ) { 10270 complete( evt.type === "error" ? 404 : 200, evt.type ); 10271 } 10272 } ); 10273 10274 // Use native DOM manipulation to avoid our domManip AJAX trickery 10275 document.head.appendChild( script[ 0 ] ); 10276 }, 10277 abort: function() { 10278 if ( callback ) { 10279 callback(); 10280 } 10281 } 10282 }; 10283 } 10284} ); 10285 10286 10287 10288 10289var oldCallbacks = [], 10290 rjsonp = /(=)\?(?=&|$)|\?\?/; 10291 10292// Default jsonp settings 10293jQuery.ajaxSetup( { 10294 jsonp: "callback", 10295 jsonpCallback: function() { 10296 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 10297 this[ callback ] = true; 10298 return callback; 10299 } 10300} ); 10301 10302// Detect, normalize options and install callbacks for jsonp requests 10303jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 10304 10305 var callbackName, overwritten, responseContainer, 10306 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 10307 "url" : 10308 typeof s.data === "string" && 10309 ( s.contentType || "" ) 10310 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 10311 rjsonp.test( s.data ) && "data" 10312 ); 10313 10314 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10315 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 10316 10317 // Get callback name, remembering preexisting value associated with it 10318 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 10319 s.jsonpCallback() : 10320 s.jsonpCallback; 10321 10322 // Insert callback into url or form data 10323 if ( jsonProp ) { 10324 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 10325 } else if ( s.jsonp !== false ) { 10326 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 10327 } 10328 10329 // Use data converter to retrieve json after script execution 10330 s.converters[ "script json" ] = function() { 10331 if ( !responseContainer ) { 10332 jQuery.error( callbackName + " was not called" ); 10333 } 10334 return responseContainer[ 0 ]; 10335 }; 10336 10337 // Force json dataType 10338 s.dataTypes[ 0 ] = "json"; 10339 10340 // Install callback 10341 overwritten = window[ callbackName ]; 10342 window[ callbackName ] = function() { 10343 responseContainer = arguments; 10344 }; 10345 10346 // Clean-up function (fires after converters) 10347 jqXHR.always( function() { 10348 10349 // If previous value didn't exist - remove it 10350 if ( overwritten === undefined ) { 10351 jQuery( window ).removeProp( callbackName ); 10352 10353 // Otherwise restore preexisting value 10354 } else { 10355 window[ callbackName ] = overwritten; 10356 } 10357 10358 // Save back as free 10359 if ( s[ callbackName ] ) { 10360 10361 // Make sure that re-using the options doesn't screw things around 10362 s.jsonpCallback = originalSettings.jsonpCallback; 10363 10364 // Save the callback name for future use 10365 oldCallbacks.push( callbackName ); 10366 } 10367 10368 // Call if it was a function and we have a response 10369 if ( responseContainer && isFunction( overwritten ) ) { 10370 overwritten( responseContainer[ 0 ] ); 10371 } 10372 10373 responseContainer = overwritten = undefined; 10374 } ); 10375 10376 // Delegate to script 10377 return "script"; 10378 } 10379} ); 10380 10381 10382 10383 10384// Support: Safari 8 only 10385// In Safari 8 documents created via document.implementation.createHTMLDocument 10386// collapse sibling forms: the second one becomes a child of the first one. 10387// Because of that, this security measure has to be disabled in Safari 8. 10388// https://bugs.webkit.org/show_bug.cgi?id=137337 10389support.createHTMLDocument = ( function() { 10390 var body = document.implementation.createHTMLDocument( "" ).body; 10391 body.innerHTML = "<form></form><form></form>"; 10392 return body.childNodes.length === 2; 10393} )(); 10394 10395 10396// Argument "data" should be string of html 10397// context (optional): If specified, the fragment will be created in this context, 10398// defaults to document 10399// keepScripts (optional): If true, will include scripts passed in the html string 10400jQuery.parseHTML = function( data, context, keepScripts ) { 10401 if ( typeof data !== "string" ) { 10402 return []; 10403 } 10404 if ( typeof context === "boolean" ) { 10405 keepScripts = context; 10406 context = false; 10407 } 10408 10409 var base, parsed, scripts; 10410 10411 if ( !context ) { 10412 10413 // Stop scripts or inline event handlers from being executed immediately 10414 // by using document.implementation 10415 if ( support.createHTMLDocument ) { 10416 context = document.implementation.createHTMLDocument( "" ); 10417 10418 // Set the base href for the created document 10419 // so any parsed elements with URLs 10420 // are based on the document's URL (gh-2965) 10421 base = context.createElement( "base" ); 10422 base.href = document.location.href; 10423 context.head.appendChild( base ); 10424 } else { 10425 context = document; 10426 } 10427 } 10428 10429 parsed = rsingleTag.exec( data ); 10430 scripts = !keepScripts && []; 10431 10432 // Single tag 10433 if ( parsed ) { 10434 return [ context.createElement( parsed[ 1 ] ) ]; 10435 } 10436 10437 parsed = buildFragment( [ data ], context, scripts ); 10438 10439 if ( scripts && scripts.length ) { 10440 jQuery( scripts ).remove(); 10441 } 10442 10443 return jQuery.merge( [], parsed.childNodes ); 10444}; 10445 10446 10447/** 10448 * Load a url into a page 10449 */ 10450jQuery.fn.load = function( url, params, callback ) { 10451 var selector, type, response, 10452 self = this, 10453 off = url.indexOf( " " ); 10454 10455 if ( off > -1 ) { 10456 selector = stripAndCollapse( url.slice( off ) ); 10457 url = url.slice( 0, off ); 10458 } 10459 10460 // If it's a function 10461 if ( isFunction( params ) ) { 10462 10463 // We assume that it's the callback 10464 callback = params; 10465 params = undefined; 10466 10467 // Otherwise, build a param string 10468 } else if ( params && typeof params === "object" ) { 10469 type = "POST"; 10470 } 10471 10472 // If we have elements to modify, make the request 10473 if ( self.length > 0 ) { 10474 jQuery.ajax( { 10475 url: url, 10476 10477 // If "type" variable is undefined, then "GET" method will be used. 10478 // Make value of this field explicit since 10479 // user can override it through ajaxSetup method 10480 type: type || "GET", 10481 dataType: "html", 10482 data: params 10483 } ).done( function( responseText ) { 10484 10485 // Save response for use in complete callback 10486 response = arguments; 10487 10488 self.html( selector ? 10489 10490 // If a selector was specified, locate the right elements in a dummy div 10491 // Exclude scripts to avoid IE 'Permission Denied' errors 10492 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 10493 10494 // Otherwise use the full result 10495 responseText ); 10496 10497 // If the request succeeds, this function gets "data", "status", "jqXHR" 10498 // but they are ignored because response was set above. 10499 // If it fails, this function gets "jqXHR", "status", "error" 10500 } ).always( callback && function( jqXHR, status ) { 10501 self.each( function() { 10502 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 10503 } ); 10504 } ); 10505 } 10506 10507 return this; 10508}; 10509 10510 10511 10512 10513jQuery.expr.pseudos.animated = function( elem ) { 10514 return jQuery.grep( jQuery.timers, function( fn ) { 10515 return elem === fn.elem; 10516 } ).length; 10517}; 10518 10519 10520 10521 10522jQuery.offset = { 10523 setOffset: function( elem, options, i ) { 10524 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 10525 position = jQuery.css( elem, "position" ), 10526 curElem = jQuery( elem ), 10527 props = {}; 10528 10529 // Set position first, in-case top/left are set even on static elem 10530 if ( position === "static" ) { 10531 elem.style.position = "relative"; 10532 } 10533 10534 curOffset = curElem.offset(); 10535 curCSSTop = jQuery.css( elem, "top" ); 10536 curCSSLeft = jQuery.css( elem, "left" ); 10537 calculatePosition = ( position === "absolute" || position === "fixed" ) && 10538 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 10539 10540 // Need to be able to calculate position if either 10541 // top or left is auto and position is either absolute or fixed 10542 if ( calculatePosition ) { 10543 curPosition = curElem.position(); 10544 curTop = curPosition.top; 10545 curLeft = curPosition.left; 10546 10547 } else { 10548 curTop = parseFloat( curCSSTop ) || 0; 10549 curLeft = parseFloat( curCSSLeft ) || 0; 10550 } 10551 10552 if ( isFunction( options ) ) { 10553 10554 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10555 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 10556 } 10557 10558 if ( options.top != null ) { 10559 props.top = ( options.top - curOffset.top ) + curTop; 10560 } 10561 if ( options.left != null ) { 10562 props.left = ( options.left - curOffset.left ) + curLeft; 10563 } 10564 10565 if ( "using" in options ) { 10566 options.using.call( elem, props ); 10567 10568 } else { 10569 curElem.css( props ); 10570 } 10571 } 10572}; 10573 10574jQuery.fn.extend( { 10575 10576 // offset() relates an element's border box to the document origin 10577 offset: function( options ) { 10578 10579 // Preserve chaining for setter 10580 if ( arguments.length ) { 10581 return options === undefined ? 10582 this : 10583 this.each( function( i ) { 10584 jQuery.offset.setOffset( this, options, i ); 10585 } ); 10586 } 10587 10588 var rect, win, 10589 elem = this[ 0 ]; 10590 10591 if ( !elem ) { 10592 return; 10593 } 10594 10595 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 10596 // Support: IE <=11 only 10597 // Running getBoundingClientRect on a 10598 // disconnected node in IE throws an error 10599 if ( !elem.getClientRects().length ) { 10600 return { top: 0, left: 0 }; 10601 } 10602 10603 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 10604 rect = elem.getBoundingClientRect(); 10605 win = elem.ownerDocument.defaultView; 10606 return { 10607 top: rect.top + win.pageYOffset, 10608 left: rect.left + win.pageXOffset 10609 }; 10610 }, 10611 10612 // position() relates an element's margin box to its offset parent's padding box 10613 // This corresponds to the behavior of CSS absolute positioning 10614 position: function() { 10615 if ( !this[ 0 ] ) { 10616 return; 10617 } 10618 10619 var offsetParent, offset, doc, 10620 elem = this[ 0 ], 10621 parentOffset = { top: 0, left: 0 }; 10622 10623 // position:fixed elements are offset from the viewport, which itself always has zero offset 10624 if ( jQuery.css( elem, "position" ) === "fixed" ) { 10625 10626 // Assume position:fixed implies availability of getBoundingClientRect 10627 offset = elem.getBoundingClientRect(); 10628 10629 } else { 10630 offset = this.offset(); 10631 10632 // Account for the *real* offset parent, which can be the document or its root element 10633 // when a statically positioned element is identified 10634 doc = elem.ownerDocument; 10635 offsetParent = elem.offsetParent || doc.documentElement; 10636 while ( offsetParent && 10637 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 10638 jQuery.css( offsetParent, "position" ) === "static" ) { 10639 10640 offsetParent = offsetParent.parentNode; 10641 } 10642 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 10643 10644 // Incorporate borders into its offset, since they are outside its content origin 10645 parentOffset = jQuery( offsetParent ).offset(); 10646 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 10647 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 10648 } 10649 } 10650 10651 // Subtract parent offsets and element margins 10652 return { 10653 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 10654 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 10655 }; 10656 }, 10657 10658 // This method will return documentElement in the following cases: 10659 // 1) For the element inside the iframe without offsetParent, this method will return 10660 // documentElement of the parent window 10661 // 2) For the hidden or detached element 10662 // 3) For body or html element, i.e. in case of the html node - it will return itself 10663 // 10664 // but those exceptions were never presented as a real life use-cases 10665 // and might be considered as more preferable results. 10666 // 10667 // This logic, however, is not guaranteed and can change at any point in the future 10668 offsetParent: function() { 10669 return this.map( function() { 10670 var offsetParent = this.offsetParent; 10671 10672 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 10673 offsetParent = offsetParent.offsetParent; 10674 } 10675 10676 return offsetParent || documentElement; 10677 } ); 10678 } 10679} ); 10680 10681// Create scrollLeft and scrollTop methods 10682jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 10683 var top = "pageYOffset" === prop; 10684 10685 jQuery.fn[ method ] = function( val ) { 10686 return access( this, function( elem, method, val ) { 10687 10688 // Coalesce documents and windows 10689 var win; 10690 if ( isWindow( elem ) ) { 10691 win = elem; 10692 } else if ( elem.nodeType === 9 ) { 10693 win = elem.defaultView; 10694 } 10695 10696 if ( val === undefined ) { 10697 return win ? win[ prop ] : elem[ method ]; 10698 } 10699 10700 if ( win ) { 10701 win.scrollTo( 10702 !top ? val : win.pageXOffset, 10703 top ? val : win.pageYOffset 10704 ); 10705 10706 } else { 10707 elem[ method ] = val; 10708 } 10709 }, method, val, arguments.length ); 10710 }; 10711} ); 10712 10713// Support: Safari <=7 - 9.1, Chrome <=37 - 49 10714// Add the top/left cssHooks using jQuery.fn.position 10715// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10716// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 10717// getComputedStyle returns percent when specified for top/left/bottom/right; 10718// rather than make the css module depend on the offset module, just check for it here 10719jQuery.each( [ "top", "left" ], function( _i, prop ) { 10720 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 10721 function( elem, computed ) { 10722 if ( computed ) { 10723 computed = curCSS( elem, prop ); 10724 10725 // If curCSS returns percentage, fallback to offset 10726 return rnumnonpx.test( computed ) ? 10727 jQuery( elem ).position()[ prop ] + "px" : 10728 computed; 10729 } 10730 } 10731 ); 10732} ); 10733 10734 10735// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10736jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 10737 jQuery.each( { 10738 padding: "inner" + name, 10739 content: type, 10740 "": "outer" + name 10741 }, function( defaultExtra, funcName ) { 10742 10743 // Margin is only for outerHeight, outerWidth 10744 jQuery.fn[ funcName ] = function( margin, value ) { 10745 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 10746 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 10747 10748 return access( this, function( elem, type, value ) { 10749 var doc; 10750 10751 if ( isWindow( elem ) ) { 10752 10753 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 10754 return funcName.indexOf( "outer" ) === 0 ? 10755 elem[ "inner" + name ] : 10756 elem.document.documentElement[ "client" + name ]; 10757 } 10758 10759 // Get document width or height 10760 if ( elem.nodeType === 9 ) { 10761 doc = elem.documentElement; 10762 10763 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10764 // whichever is greatest 10765 return Math.max( 10766 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 10767 elem.body[ "offset" + name ], doc[ "offset" + name ], 10768 doc[ "client" + name ] 10769 ); 10770 } 10771 10772 return value === undefined ? 10773 10774 // Get width or height on the element, requesting but not forcing parseFloat 10775 jQuery.css( elem, type, extra ) : 10776 10777 // Set width or height on the element 10778 jQuery.style( elem, type, value, extra ); 10779 }, type, chainable ? margin : undefined, chainable ); 10780 }; 10781 } ); 10782} ); 10783 10784 10785jQuery.each( [ 10786 "ajaxStart", 10787 "ajaxStop", 10788 "ajaxComplete", 10789 "ajaxError", 10790 "ajaxSuccess", 10791 "ajaxSend" 10792], function( _i, type ) { 10793 jQuery.fn[ type ] = function( fn ) { 10794 return this.on( type, fn ); 10795 }; 10796} ); 10797 10798 10799 10800 10801jQuery.fn.extend( { 10802 10803 bind: function( types, data, fn ) { 10804 return this.on( types, null, data, fn ); 10805 }, 10806 unbind: function( types, fn ) { 10807 return this.off( types, null, fn ); 10808 }, 10809 10810 delegate: function( selector, types, data, fn ) { 10811 return this.on( types, selector, data, fn ); 10812 }, 10813 undelegate: function( selector, types, fn ) { 10814 10815 // ( namespace ) or ( selector, types [, fn] ) 10816 return arguments.length === 1 ? 10817 this.off( selector, "**" ) : 10818 this.off( types, selector || "**", fn ); 10819 }, 10820 10821 hover: function( fnOver, fnOut ) { 10822 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 10823 } 10824} ); 10825 10826jQuery.each( 10827 ( "blur focus focusin focusout resize scroll click dblclick " + 10828 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 10829 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 10830 function( _i, name ) { 10831 10832 // Handle event binding 10833 jQuery.fn[ name ] = function( data, fn ) { 10834 return arguments.length > 0 ? 10835 this.on( name, null, data, fn ) : 10836 this.trigger( name ); 10837 }; 10838 } 10839); 10840 10841 10842 10843 10844// Support: Android <=4.0 only 10845// Make sure we trim BOM and NBSP 10846var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 10847 10848// Bind a function to a context, optionally partially applying any 10849// arguments. 10850// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 10851// However, it is not slated for removal any time soon 10852jQuery.proxy = function( fn, context ) { 10853 var tmp, args, proxy; 10854 10855 if ( typeof context === "string" ) { 10856 tmp = fn[ context ]; 10857 context = fn; 10858 fn = tmp; 10859 } 10860 10861 // Quick check to determine if target is callable, in the spec 10862 // this throws a TypeError, but we will just return undefined. 10863 if ( !isFunction( fn ) ) { 10864 return undefined; 10865 } 10866 10867 // Simulated bind 10868 args = slice.call( arguments, 2 ); 10869 proxy = function() { 10870 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 10871 }; 10872 10873 // Set the guid of unique handler to the same of original handler, so it can be removed 10874 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 10875 10876 return proxy; 10877}; 10878 10879jQuery.holdReady = function( hold ) { 10880 if ( hold ) { 10881 jQuery.readyWait++; 10882 } else { 10883 jQuery.ready( true ); 10884 } 10885}; 10886jQuery.isArray = Array.isArray; 10887jQuery.parseJSON = JSON.parse; 10888jQuery.nodeName = nodeName; 10889jQuery.isFunction = isFunction; 10890jQuery.isWindow = isWindow; 10891jQuery.camelCase = camelCase; 10892jQuery.type = toType; 10893 10894jQuery.now = Date.now; 10895 10896jQuery.isNumeric = function( obj ) { 10897 10898 // As of jQuery 3.0, isNumeric is limited to 10899 // strings and numbers (primitives or objects) 10900 // that can be coerced to finite numbers (gh-2662) 10901 var type = jQuery.type( obj ); 10902 return ( type === "number" || type === "string" ) && 10903 10904 // parseFloat NaNs numeric-cast false positives ("") 10905 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 10906 // subtraction forces infinities to NaN 10907 !isNaN( obj - parseFloat( obj ) ); 10908}; 10909 10910jQuery.trim = function( text ) { 10911 return text == null ? 10912 "" : 10913 ( text + "" ).replace( rtrim, "" ); 10914}; 10915 10916 10917 10918// Register as a named AMD module, since jQuery can be concatenated with other 10919// files that may use define, but not via a proper concatenation script that 10920// understands anonymous AMD modules. A named AMD is safest and most robust 10921// way to register. Lowercase jquery is used because AMD module names are 10922// derived from file names, and jQuery is normally delivered in a lowercase 10923// file name. Do this after creating the global so that if an AMD module wants 10924// to call noConflict to hide this version of jQuery, it will work. 10925 10926// Note that for maximum portability, libraries that are not jQuery should 10927// declare themselves as anonymous modules, and avoid setting a global if an 10928// AMD loader is present. jQuery is a special case. For more information, see 10929// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10930 10931if ( t
10931rue ) { 10932 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { 10933 return jQuery; 10934 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 10935 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 10936} 10937 10938 10939 10940 10941var 10942 10943 // Map over jQuery in case of overwrite 10944 _jQuery = window.jQuery, 10945 10946 // Map over the $ in case of overwrite 10947 _$ = window.$; 10948 10949jQuery.noConflict = function( deep ) { 10950 if ( window.$ === jQuery ) { 10951 window.$ = _$; 10952 } 10953 10954 if ( deep && window.jQuery === jQuery ) { 10955 window.jQuery = _jQuery; 10956 } 10957 10958 return jQuery; 10959}; 10960 10961// Expose jQuery and $ identifiers, even in AMD 10962// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 10963// and CommonJS for browser emulators (#13566) 10964if ( typeof noGlobal === "undefined" ) { 10965 window.jQuery = window.$ = jQuery; 10966} 10967 10968 10969 10970 10971return jQuery; 10972} ); 10973 10974 10975/***/ }), 10976/* 1 */ 10977/***/ (function(module, exports, __webpack_require__) { 10978 10979var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! DataTables 1.11.3 10980 * ©2008-2021 SpryMedia Ltd - datatables.net/license 10981 */ 10982 10983/** 10984 * @summary DataTables 10985 * @description Paginate, search and order HTML tables 10986 * @version 1.11.3 10987 * @file jquery.dataTables.js 10988 * @author SpryMedia Ltd 10989 * @contact www.datatables.net 10990 * @copyright Copyright 2008-2021 SpryMedia Ltd. 10991 * 10992 * This source file is free software, available under the following license: 10993 * MIT license - http://datatables.net/license 10994 * 10995 * This source file is distributed in the hope that it will be useful, but 10996 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 10997 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. 10998 * 10999 * For details please refer to: http://www.datatables.net 11000 */ 11001 11002/*jslint evil: true, undef: true, browser: true */ 11003/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ 11004 11005(function( factory ) { 11006 "use strict"; 11007 11008 if ( true ) { 11009 // AMD 11010 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) { 11011 return factory( $, window, document ); 11012 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 11013 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 11014 } 11015 else {} 11016} 11017(function( $, window, document, undefined ) { 11018 "use strict"; 11019 11020 /** 11021 * DataTables is a plug-in for the jQuery Javascript library. It is a highly 11022 * flexible tool, based upon the foundations of progressive enhancement, 11023 * which will add advanced interaction controls to any HTML table. For a 11024 * full list of features please refer to 11025 * [DataTables.net](href="http://datatables.net). 11026 * 11027 * Note that the `DataTable` object is not a global variable but is aliased 11028 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may 11029 * be accessed. 11030 * 11031 * @class 11032 * @param {object} [init={}] Configuration object for DataTables. Options 11033 * are defined by {@link DataTable.defaults} 11034 * @requires jQuery 1.7+ 11035 * 11036 * @example 11037 * // Basic initialisation 11038 * $(document).ready( function { 11039 * $('#example').dataTable(); 11040 * } ); 11041 * 11042 * @example 11043 * // Initialisation with configuration options - in this case, disable 11044 * // pagination and sorting. 11045 * $(document).ready( function { 11046 * $('#example').dataTable( { 11047 * "paginate": false, 11048 * "sort": false 11049 * } ); 11050 * } ); 11051 */ 11052 var DataTable = function ( selector, options ) 11053 { 11054 // When creating with `new`, create a new DataTable, returning the API instance 11055 if (this instanceof DataTable) { 11056 return $(selector).DataTable(options); 11057 } 11058 else { 11059 // Argument switching 11060 options = selector; 11061 }
vendor: 25,075 bytes, lines 11062-11817
11062 11063 /** 11064 * Perform a jQuery selector action on the table's TR elements (from the tbody) and 11065 * return the resulting jQuery object. 11066 * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on 11067 * @param {object} [oOpts] Optional parameters for modifying the rows to be included 11068 * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter 11069 * criterion ("applied") or all TR elements (i.e. no filter). 11070 * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. 11071 * Can be either 'current', whereby the current sorting of the table is used, or 11072 * 'original' whereby the original order the data was read into the table is used. 11073 * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page 11074 * ("current") or not ("all"). If 'current' is given, then order is assumed to be 11075 * 'current' and filter is 'applied', regardless of what they might be given as. 11076 * @returns {object} jQuery object, filtered by the given selector. 11077 * @dtopt API 11078 * @deprecated Since v1.10 11079 * 11080 * @example 11081 * $(document).ready(function() { 11082 * var oTable = $('#example').dataTable(); 11083 * 11084 * // Highlight every second row 11085 * oTable.$('tr:odd').css('backgroundColor', 'blue'); 11086 * } ); 11087 * 11088 * @example 11089 * $(document).ready(function() { 11090 * var oTable = $('#example').dataTable(); 11091 * 11092 * // Filter to rows with 'Webkit' in them, add a background colour and then 11093 * // remove the filter, thus highlighting the 'Webkit' rows only. 11094 * oTable.fnFilter('Webkit'); 11095 * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue'); 11096 * oTable.fnFilter(''); 11097 * } ); 11098 */ 11099 this.$ = function ( sSelector, oOpts ) 11100 { 11101 return this.api(true).$( sSelector, oOpts ); 11102 }; 11103 11104 11105 /** 11106 * Almost identical to $ in operation, but in this case returns the data for the matched 11107 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes 11108 * rather than any descendants, so the data can be obtained for the row/cell. If matching 11109 * rows are found, the data returned is the original data array/object that was used to 11110 * create the row (or a generated array if from a DOM source). 11111 * 11112 * This method is often useful in-combination with $ where both functions are given the 11113 * same parameters and the array indexes will match identically. 11114 * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on 11115 * @param {object} [oOpts] Optional parameters for modifying the rows to be included 11116 * @param {string} [oOpts.filter=none] Select elements that meet the current filter 11117 * criterion ("applied") or all elements (i.e. no filter). 11118 * @param {string} [oOpts.order=current] Order of the data in the processed array. 11119 * Can be either 'current', whereby the current sorting of the table is used, or 11120 * 'original' whereby the original order the data was read into the table is used. 11121 * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page 11122 * ("current") or not ("all"). If 'current' is given, then order is assumed to be 11123 * 'current' and filter is 'applied', regardless of what they might be given as. 11124 * @returns {array} Data for the matched elements. If any elements, as a result of the 11125 * selector, were not TR, TD or TH elements in the DataTable, they will have a null 11126 * entry in the array. 11127 * @dtopt API 11128 * @deprecated Since v1.10 11129 * 11130 * @example 11131 * $(document).ready(function() { 11132 * var oTable = $('#example').dataTable(); 11133 * 11134 * // Get the data from the first row in the table 11135 * var data = oTable._('tr:first'); 11136 * 11137 * // Do something useful with the data 11138 * alert( "First cell is: "+data[0] ); 11139 * } ); 11140 * 11141 * @example 11142 * $(document).ready(function() { 11143 * var oTable = $('#example').dataTable(); 11144 * 11145 * // Filter to 'Webkit' and get all data for 11146 * oTable.fnFilter('Webkit'); 11147 * var data = oTable._('tr', {"search": "applied"}); 11148 * 11149 * // Do something with the data 11150 * alert( data.length+" rows matched the search" ); 11151 * } ); 11152 */ 11153 this._ = function ( sSelector, oOpts ) 11154 { 11155 return this.api(true).rows( sSelector, oOpts ).data(); 11156 }; 11157 11158 11159 /** 11160 * Create a DataTables Api instance, with the currently selected tables for 11161 * the Api's context. 11162 * @param {boolean} [traditional=false] Set the API instance's context to be 11163 * only the table referred to by the `DataTable.ext.iApiIndex` option, as was 11164 * used in the API presented by DataTables 1.9- (i.e. the traditional mode), 11165 * or if all tables captured in the jQuery object should be used. 11166 * @return {DataTables.Api} 11167 */ 11168 this.api = function ( traditional ) 11169 { 11170 return traditional ? 11171 new _Api( 11172 _fnSettingsFromNode( this[ _ext.iApiIndex ] ) 11173 ) : 11174 new _Api( this ); 11175 }; 11176 11177 11178 /** 11179 * Add a single new row or multiple rows of data to the table. Please note 11180 * that this is suitable for client-side processing only - if you are using 11181 * server-side processing (i.e. "bServerSide": true), then to add data, you 11182 * must add it to the data source, i.e. the server-side, through an Ajax call. 11183 * @param {array|object} data The data to be added to the table. This can be: 11184 * <ul> 11185 * <li>1D array of data - add a single row with the data provided</li> 11186 * <li>2D array of arrays - add multiple rows in a single call</li> 11187 * <li>object - data object when using <i>mData</i></li> 11188 * <li>array of objects - multiple data objects when using <i>mData</i></li> 11189 * </ul> 11190 * @param {bool} [redraw=true] redraw the table or not 11191 * @returns {array} An array of integers, representing the list of indexes in 11192 * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to 11193 * the table. 11194 * @dtopt API 11195 * @deprecated Since v1.10 11196 * 11197 * @example 11198 * // Global var for counter 11199 * var giCount = 2; 11200 * 11201 * $(document).ready(function() { 11202 * $('#example').dataTable(); 11203 * } ); 11204 * 11205 * function fnClickAddRow() { 11206 * $('#example').dataTable().fnAddData( [ 11207 * giCount+".1", 11208 * giCount+".2", 11209 * giCount+".3", 11210 * giCount+".4" ] 11211 * ); 11212 * 11213 * giCount++; 11214 * } 11215 */ 11216 this.fnAddData = function( data, redraw ) 11217 { 11218 var api = this.api( true ); 11219 11220 /* Check if we want to add multiple rows or not */ 11221 var rows = Array.isArray(data) && ( Array.isArray(data[0]) || $.isPlainObject(data[0]) ) ? 11222 api.rows.add( data ) : 11223 api.row.add( data ); 11224 11225 if ( redraw === undefined || redraw ) { 11226 api.draw(); 11227 } 11228 11229 return rows.flatten().toArray(); 11230 }; 11231 11232 11233 /** 11234 * This function will make DataTables recalculate the column sizes, based on the data 11235 * contained in the table and the sizes applied to the columns (in the DOM, CSS or 11236 * through the sWidth parameter). This can be useful when the width of the table's 11237 * parent element changes (for example a window resize). 11238 * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to 11239 * @dtopt API 11240 * @deprecated Since v1.10 11241 * 11242 * @example 11243 * $(document).ready(function() { 11244 * var oTable = $('#example').dataTable( { 11245 * "sScrollY": "200px", 11246 * "bPaginate": false 11247 * } ); 11248 * 11249 * $(window).on('resize', function () { 11250 * oTable.fnAdjustColumnSizing(); 11251 * } ); 11252 * } ); 11253 */ 11254 this.fnAdjustColumnSizing = function ( bRedraw ) 11255 { 11256 var api = this.api( true ).columns.adjust(); 11257 var settings = api.settings()[0]; 11258 var scroll = settings.oScroll; 11259 11260 if ( bRedraw === undefined || bRedraw ) { 11261 api.draw( false ); 11262 } 11263 else if ( scroll.sX !== "" || scroll.sY !== "" ) { 11264 /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */ 11265 _fnScrollDraw( settings ); 11266 } 11267 }; 11268 11269 11270 /** 11271 * Quickly and simply clear a table 11272 * @param {bool} [bRedraw=true] redraw the table or not 11273 * @dtopt API 11274 * @deprecated Since v1.10 11275 * 11276 * @example 11277 * $(document).ready(function() { 11278 * var oTable = $('#example').dataTable(); 11279 * 11280 * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...) 11281 * oTable.fnClearTable(); 11282 * } ); 11283 */ 11284 this.fnClearTable = function( bRedraw ) 11285 { 11286 var api = this.api( true ).clear(); 11287 11288 if ( bRedraw === undefined || bRedraw ) { 11289 api.draw(); 11290 } 11291 }; 11292 11293 11294 /** 11295 * The exact opposite of 'opening' a row, this function will close any rows which 11296 * are currently 'open'. 11297 * @param {node} nTr the table row to 'close' 11298 * @returns {int} 0 on success, or 1 if failed (can't find the row) 11299 * @dtopt API 11300 * @deprecated Since v1.10 11301 * 11302 * @example 11303 * $(document).ready(function() { 11304 * var oTable; 11305 * 11306 * // 'open' an information row when a row is clicked on 11307 * $('#example tbody tr').click( function () { 11308 * if ( oTable.fnIsOpen(this) ) { 11309 * oTable.fnClose( this ); 11310 * } else { 11311 * oTable.fnOpen( this, "Temporary row opened", "info_row" ); 11312 * } 11313 * } ); 11314 * 11315 * oTable = $('#example').dataTable(); 11316 * } ); 11317 */ 11318 this.fnClose = function( nTr ) 11319 { 11320 this.api( true ).row( nTr ).child.hide(); 11321 }; 11322 11323 11324 /** 11325 * Remove a row for the table 11326 * @param {mixed} target The index of the row from aoData to be deleted, or 11327 * the TR element you want to delete 11328 * @param {function|null} [callBack] Callback function 11329 * @param {bool} [redraw=true] Redraw the table or not 11330 * @returns {array} The row that was deleted 11331 * @dtopt API 11332 * @deprecated Since v1.10 11333 * 11334 * @example 11335 * $(document).ready(function() { 11336 * var oTable = $('#example').dataTable(); 11337 * 11338 * // Immediately remove the first row 11339 * oTable.fnDeleteRow( 0 ); 11340 * } ); 11341 */ 11342 this.fnDeleteRow = function( target, callback, redraw ) 11343 { 11344 var api = this.api( true ); 11345 var rows = api.rows( target ); 11346 var settings = rows.settings()[0]; 11347 var data = settings.aoData[ rows[0][0] ]; 11348 11349 rows.remove(); 11350 11351 if ( callback ) { 11352 callback.call( this, settings, data ); 11353 } 11354 11355 if ( redraw === undefined || redraw ) { 11356 api.draw(); 11357 } 11358 11359 return data; 11360 }; 11361 11362 11363 /** 11364 * Restore the table to it's original state in the DOM by removing all of DataTables 11365 * enhancements, alterations to the DOM structure of the table and event listeners. 11366 * @param {boolean} [remove=false] Completely remove the table from the DOM 11367 * @dtopt API 11368 * @deprecated Since v1.10 11369 * 11370 * @example 11371 * $(document).ready(function() { 11372 * // This example is fairly pointless in reality, but shows how fnDestroy can be used 11373 * var oTable = $('#example').dataTable(); 11374 * oTable.fnDestroy(); 11375 * } ); 11376 */ 11377 this.fnDestroy = function ( remove ) 11378 { 11379 this.api( true ).destroy( remove ); 11380 }; 11381 11382 11383 /** 11384 * Redraw the table 11385 * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw. 11386 * @dtopt API 11387 * @deprecated Since v1.10 11388 * 11389 * @example 11390 * $(document).ready(function() { 11391 * var oTable = $('#example').dataTable(); 11392 * 11393 * // Re-draw the table - you wouldn't want to do it here, but it's an example :-) 11394 * oTable.fnDraw(); 11395 * } ); 11396 */ 11397 this.fnDraw = function( complete ) 11398 { 11399 // Note that this isn't an exact match to the old call to _fnDraw - it takes 11400 // into account the new data, but can hold position. 11401 this.api( true ).draw( complete ); 11402 }; 11403 11404 11405 /** 11406 * Filter the input based on data 11407 * @param {string} sInput String to filter the table on 11408 * @param {int|null} [iColumn] Column to limit filtering to 11409 * @param {bool} [bRegex=false] Treat as regular expression or not 11410 * @param {bool} [bSmart=true] Perform smart filtering or not 11411 * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es) 11412 * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false) 11413 * @dtopt API 11414 * @deprecated Since v1.10 11415 * 11416 * @example 11417 * $(document).ready(function() { 11418 * var oTable = $('#example').dataTable(); 11419 * 11420 * // Sometime later - filter... 11421 * oTable.fnFilter( 'test string' ); 11422 * } ); 11423 */ 11424 this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive ) 11425 { 11426 var api = this.api( true ); 11427 11428 if ( iColumn === null || iColumn === undefined ) { 11429 api.search( sInput, bRegex, bSmart, bCaseInsensitive ); 11430 } 11431 else { 11432 api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive ); 11433 } 11434 11435 api.draw(); 11436 }; 11437 11438 11439 /** 11440 * Get the data for the whole table, an individual row or an individual cell based on the 11441 * provided parameters. 11442 * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as 11443 * a TR node then the data source for the whole row will be returned. If given as a 11444 * TD/TH cell node then iCol will be automatically calculated and the data for the 11445 * cell returned. If given as an integer, then this is treated as the aoData internal 11446 * data index for the row (see fnGetPosition) and the data for that row used. 11447 * @param {int} [col] Optional column index that you want the data of. 11448 * @returns {array|object|string} If mRow is undefined, then the data for all rows is 11449 * returned. If mRow is defined, just data for that row, and is iCol is 11450 * defined, only data for the designated cell is returned. 11451 * @dtopt API 11452 * @deprecated Since v1.10 11453 * 11454 * @example 11455 * // Row data 11456 * $(document).ready(function() { 11457 * oTable = $('#example').dataTable(); 11458 * 11459 * oTable.$('tr').click( function () { 11460 * var data = oTable.fnGetData( this ); 11461 * // ... do something with the array / object of data for the row 11462 * } ); 11463 * } ); 11464 * 11465 * @example 11466 * // Individual cell data 11467 * $(document).ready(function() { 11468 * oTable = $('#example').dataTable(); 11469 * 11470 * oTable.$('td').click( function () { 11471 * var sData = oTable.fnGetData( this ); 11472 * alert( 'The cell clicked on had the value of '+sData ); 11473 * } ); 11474 * } ); 11475 */ 11476 this.fnGetData = function( src, col ) 11477 { 11478 var api = this.api( true ); 11479 11480 if ( src !== undefined ) { 11481 var type = src.nodeName ? src.nodeName.toLowerCase() : ''; 11482 11483 return col !== undefined || type == 'td' || type == 'th' ? 11484 api.cell( src, col ).data() : 11485 api.row( src ).data() || null; 11486 } 11487 11488 return api.data().toArray(); 11489 }; 11490 11491 11492 /** 11493 * Get an array of the TR nodes that are used in the table's body. Note that you will 11494 * typically want to use the '$' API method in preference to this as it is more 11495 * flexible. 11496 * @param {int} [iRow] Optional row index for the TR element you want 11497 * @returns {array|node} If iRow is undefined, returns an array of all TR elements 11498 * in the table's body, or iRow is defined, just the TR element requested. 11499 * @dtopt API 11500 * @deprecated Since v1.10 11501 * 11502 * @example 11503 * $(document).ready(function() { 11504 * var oTable = $('#example').dataTable(); 11505 * 11506 * // Get the nodes from the table 11507 * var nNodes = oTable.fnGetNodes( ); 11508 * } ); 11509 */ 11510 this.fnGetNodes = function( iRow ) 11511 { 11512 var api = this.api( true ); 11513 11514 return iRow !== undefined ? 11515 api.row( iRow ).node() : 11516 api.rows().nodes().flatten().toArray(); 11517 }; 11518 11519 11520 /** 11521 * Get the array indexes of a particular cell from it's DOM element 11522 * and column index including hidden columns 11523 * @param {node} node this can either be a TR, TD or TH in the table's body 11524 * @returns {int} If nNode is given as a TR, then a single index is returned, or 11525 * if given as a cell, an array of [row index, column index (visible), 11526 * column index (all)] is given. 11527 * @dtopt API 11528 * @deprecated Since v1.10 11529 * 11530 * @example 11531 * $(document).ready(function() { 11532 * $('#example tbody td').click( function () { 11533 * // Get the position of the current data from the node 11534 * var aPos = oTable.fnGetPosition( this ); 11535 * 11536 * // Get the data array for this row 11537 * var aData = oTable.fnGetData( aPos[0] ); 11538 * 11539 * // Update the data array and return the value 11540 * aData[ aPos[1] ] = 'clicked'; 11541 * this.innerHTML = 'clicked'; 11542 * } ); 11543 * 11544 * // Init DataTables 11545 * oTable = $('#example').dataTable(); 11546 * } ); 11547 */ 11548 this.fnGetPosition = function( node ) 11549 { 11550 var api = this.api( true ); 11551 var nodeName = node.nodeName.toUpperCase(); 11552 11553 if ( nodeName == 'TR' ) { 11554 return api.row( node ).index(); 11555 } 11556 else if ( nodeName == 'TD' || nodeName == 'TH' ) { 11557 var cell = api.cell( node ).index(); 11558 11559 return [ 11560 cell.row, 11561 cell.columnVisible, 11562 cell.column 11563 ]; 11564 } 11565 return null; 11566 }; 11567 11568 11569 /** 11570 * Check to see if a row is 'open' or not. 11571 * @param {node} nTr the table row to check 11572 * @returns {boolean} true if the row is currently open, false otherwise 11573 * @dtopt API 11574 * @deprecated Since v1.10 11575 * 11576 * @example 11577 * $(document).ready(function() { 11578 * var oTable; 11579 * 11580 * // 'open' an information row when a row is clicked on 11581 * $('#example tbody tr').click( function () { 11582 * if ( oTable.fnIsOpen(this) ) { 11583 * oTable.fnClose( this ); 11584 * } else { 11585 * oTable.fnOpen( this, "Temporary row opened", "info_row" ); 11586 * } 11587 * } ); 11588 * 11589 * oTable = $('#example').dataTable(); 11590 * } ); 11591 */ 11592 this.fnIsOpen = function( nTr ) 11593 { 11594 return this.api( true ).row( nTr ).child.isShown(); 11595 }; 11596 11597 11598 /** 11599 * This function will place a new row directly after a row which is currently 11600 * on display on the page, with the HTML contents that is passed into the 11601 * function. This can be used, for example, to ask for confirmation that a 11602 * particular record should be deleted. 11603 * @param {node} nTr The table row to 'open' 11604 * @param {string|node|jQuery} mHtml The HTML to put into the row 11605 * @param {string} sClass Class to give the new TD cell 11606 * @returns {node} The row opened. Note that if the table row passed in as the 11607 * first parameter, is not found in the table, this method will silently 11608 * return. 11609 * @dtopt API 11610 * @deprecated Since v1.10 11611 * 11612 * @example 11613 * $(document).ready(function() { 11614 * var oTable; 11615 * 11616 * // 'open' an information row when a row is clicked on 11617 * $('#example tbody tr').click( function () { 11618 * if ( oTable.fnIsOpen(this) ) { 11619 * oTable.fnClose( this ); 11620 * } else { 11621 * oTable.fnOpen( this, "Temporary row opened", "info_row" ); 11622 * } 11623 * } ); 11624 * 11625 * oTable = $('#example').dataTable(); 11626 * } ); 11627 */ 11628 this.fnOpen = function( nTr, mHtml, sClass ) 11629 { 11630 return this.api( true ) 11631 .row( nTr ) 11632 .child( mHtml, sClass ) 11633 .show() 11634 .child()[0]; 11635 }; 11636 11637 11638 /** 11639 * Change the pagination - provides the internal logic for pagination in a simple API 11640 * function. With this function you can have a DataTables table go to the next, 11641 * previous, first or last pages. 11642 * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" 11643 * or page number to jump to (integer), note that page 0 is the first page. 11644 * @param {bool} [bRedraw=true] Redraw the table or not 11645 * @dtopt API 11646 * @deprecated Since v1.10 11647 * 11648 * @example 11649 * $(document).ready(function() { 11650 * var oTable = $('#example').dataTable(); 11651 * oTable.fnPageChange( 'next' ); 11652 * } ); 11653 */ 11654 this.fnPageChange = function ( mAction, bRedraw ) 11655 { 11656 var api = this.api( true ).page( mAction ); 11657 11658 if ( bRedraw === undefined || bRedraw ) { 11659 api.draw(false); 11660 } 11661 }; 11662 11663 11664 /** 11665 * Show a particular column 11666 * @param {int} iCol The column whose display should be changed 11667 * @param {bool} bShow Show (true) or hide (false) the column 11668 * @param {bool} [bRedraw=true] Redraw the table or not 11669 * @dtopt API 11670 * @deprecated Since v1.10 11671 * 11672 * @example 11673 * $(document).ready(function() { 11674 * var oTable = $('#example').dataTable(); 11675 * 11676 * // Hide the second column after initialisation 11677 * oTable.fnSetColumnVis( 1, false ); 11678 * } ); 11679 */ 11680 this.fnSetColumnVis = function ( iCol, bShow, bRedraw ) 11681 { 11682 var api = this.api( true ).column( iCol ).visible( bShow ); 11683 11684 if ( bRedraw === undefined || bRedraw ) { 11685 api.columns.adjust().draw(); 11686 } 11687 }; 11688 11689 11690 /** 11691 * Get the settings for a particular table for external manipulation 11692 * @returns {object} DataTables settings object. See 11693 * {@link DataTable.models.oSettings} 11694 * @dtopt API 11695 * @deprecated Since v1.10 11696 * 11697 * @example 11698 * $(document).ready(function() { 11699 * var oTable = $('#example').dataTable(); 11700 * var oSettings = oTable.fnSettings(); 11701 * 11702 * // Show an example parameter from the settings 11703 * alert( oSettings._iDisplayStart ); 11704 * } ); 11705 */ 11706 this.fnSettings = function() 11707 { 11708 return _fnSettingsFromNode( this[_ext.iApiIndex] ); 11709 }; 11710 11711 11712 /** 11713 * Sort the table by a particular column 11714 * @param {int} iCol the data index to sort on. Note that this will not match the 11715 * 'display index' if you have hidden data entries 11716 * @dtopt API 11717 * @deprecated Since v1.10 11718 * 11719 * @example 11720 * $(document).ready(function() { 11721 * var oTable = $('#example').dataTable(); 11722 * 11723 * // Sort immediately with columns 0 and 1 11724 * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] ); 11725 * } ); 11726 */ 11727 this.fnSort = function( aaSort ) 11728 { 11729 this.api( true ).order( aaSort ).draw(); 11730 }; 11731 11732 11733 /** 11734 * Attach a sort listener to an element for a given column 11735 * @param {node} nNode the element to attach the sort listener to 11736 * @param {int} iColumn the column that a click on this node will sort on 11737 * @param {function} [fnCallback] callback function when sort is run 11738 * @dtopt API 11739 * @deprecated Since v1.10 11740 * 11741 * @example 11742 * $(document).ready(function() { 11743 * var oTable = $('#example').dataTable(); 11744 * 11745 * // Sort on column 1, when 'sorter' is clicked on 11746 * oTable.fnSortListener( document.getElementById('sorter'), 1 ); 11747 * } ); 11748 */ 11749 this.fnSortListener = function( nNode, iColumn, fnCallback ) 11750 { 11751 this.api( true ).order.listener( nNode, iColumn, fnCallback ); 11752 }; 11753 11754 11755 /** 11756 * Update a table cell or row - this method will accept either a single value to 11757 * update the cell with, an array of values with one element for each column or 11758 * an object in the same format as the original data source. The function is 11759 * self-referencing in order to make the multi column updates easier. 11760 * @param {object|array|string} mData Data to update the cell/row with 11761 * @param {node|int} mRow TR element you want to update or the aoData index 11762 * @param {int} [iColumn] The column to update, give as null or undefined to 11763 * update a whole row. 11764 * @param {bool} [bRedraw=true] Redraw the table or not 11765 * @param {bool} [bAction=true] Perform pre-draw actions or not 11766 * @returns {int} 0 on success, 1 on error 11767 * @dtopt API 11768 * @deprecated Since v1.10 11769 * 11770 * @example 11771 * $(document).ready(function() { 11772 * var oTable = $('#example').dataTable(); 11773 * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell 11774 * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row 11775 * } ); 11776 */ 11777 this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction ) 11778 { 11779 var api = this.api( true ); 11780 11781 if ( iColumn === undefined || iColumn === null ) { 11782 api.row( mRow ).data( mData ); 11783 } 11784 else { 11785 api.cell( mRow, iColumn ).data( mData ); 11786 } 11787 11788 if ( bAction === undefined || bAction ) { 11789 api.columns.adjust(); 11790 } 11791 11792 if ( bRedraw === undefined || bRedraw ) { 11793 api.draw(); 11794 } 11795 return 0; 11796 }; 11797 11798 11799 /** 11800 * Provide a common method for plug-ins to check the version of DataTables being used, in order 11801 * to ensure compatibility. 11802 * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the 11803 * formats "X" and "X.Y" are also acceptable. 11804 * @returns {boolean} true if this version of DataTables is greater or equal to the required 11805 * version, or false if this version of DataTales is not suitable 11806 * @method 11807 * @dtopt API 11808 * @deprecated Since v1.10 11809 * 11810 * @example 11811 * $(document).ready(function() { 11812 * var oTable = $('#example').dataTable(); 11813 * alert( oTable.fnVersionCheck( '1.9.0' ) ); 11814 * } ); 11815 */ 11816 this.fnVersionCheck = _ext.fnVersionCheck; 11817
vendor: 19,922 bytes, lines 11818-12488
11818 11819 var _that = this; 11820 var emptyInit = options === undefined; 11821 var len = this.length; 11822 11823 if ( emptyInit ) { 11824 options = {}; 11825 } 11826 11827 this.oApi = this.internal = _ext.internal; 11828 11829 // Extend with old style plug-in API methods 11830 for ( var fn in DataTable.ext.internal ) { 11831 if ( fn ) { 11832 this[fn] = _fnExternApiFunc(fn); 11833 } 11834 } 11835 11836 this.each(function() { 11837 // For each initialisation we want to give it a clean initialisation 11838 // object that can be bashed around 11839 var o = {}; 11840 var oInit = len > 1 ? // optimisation for single table case 11841 _fnExtend( o, options, true ) : 11842 options; 11843 11844 /*global oInit,_that,emptyInit*/ 11845 var i=0, iLen, j, jLen, k, kLen; 11846 var sId = this.getAttribute( 'id' ); 11847 var bInitHandedOff = false; 11848 var defaults = DataTable.defaults; 11849 var $this = $(this); 11850 11851 11852 /* Sanity check */ 11853 if ( this.nodeName.toLowerCase() != 'table' ) 11854 { 11855 _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); 11856 return; 11857 } 11858 11859 /* Backwards compatibility for the defaults */ 11860 _fnCompatOpts( defaults ); 11861 _fnCompatCols( defaults.column ); 11862 11863 /* Convert the camel-case defaults to Hungarian */ 11864 _fnCamelToHungarian( defaults, defaults, true ); 11865 _fnCamelToHungarian( defaults.column, defaults.column, true ); 11866 11867 /* Setting up the initialisation object */ 11868 _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true ); 11869 11870 11871 11872 /* Check to see if we are re-initialising a table */ 11873 var allSettings = DataTable.settings; 11874 for ( i=0, iLen=allSettings.length ; i<iLen ; i++ ) 11875 { 11876 var s = allSettings[i]; 11877 11878 /* Base check on table node */ 11879 if ( 11880 s.nTable == this || 11881 (s.nTHead && s.nTHead.parentNode == this) || 11882 (s.nTFoot && s.nTFoot.parentNode == this) 11883 ) { 11884 var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve; 11885 var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy; 11886 11887 if ( emptyInit || bRetrieve ) 11888 { 11889 return s.oInstance; 11890 } 11891 else if ( bDestroy ) 11892 { 11893 s.oInstance.fnDestroy(); 11894 break; 11895 } 11896 else 11897 { 11898 _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 ); 11899 return; 11900 } 11901 } 11902 11903 /* If the element we are initialising has the same ID as a table which was previously 11904 * initialised, but the table nodes don't match (from before) then we destroy the old 11905 * instance by simply deleting it. This is under the assumption that the table has been 11906 * destroyed by other methods. Anyone using non-id selectors will need to do this manually 11907 */ 11908 if ( s.sTableId == this.id ) 11909 { 11910 allSettings.splice( i, 1 ); 11911 break; 11912 } 11913 } 11914 11915 /* Ensure the table has an ID - required for accessibility */ 11916 if ( sId === null || sId === "" ) 11917 { 11918 sId = "DataTables_Table_"+(DataTable.ext._unique++); 11919 this.id = sId; 11920 } 11921 11922 /* Create the settings object for this table and set some of the default parameters */ 11923 var oSettings = $.extend( true, {}, DataTable.models.oSettings, { 11924 "sDestroyWidth": $this[0].style.width, 11925 "sInstance": sId, 11926 "sTableId": sId 11927 } ); 11928 oSettings.nTable = this; 11929 oSettings.oApi = _that.internal; 11930 oSettings.oInit = oInit; 11931 11932 allSettings.push( oSettings ); 11933 11934 // Need to add the instance after the instance after the settings object has been added 11935 // to the settings array, so we can self reference the table instance if more than one 11936 oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable(); 11937 11938 // Backwards compatibility, before we apply all the defaults 11939 _fnCompatOpts( oInit ); 11940 _fnLanguageCompat( oInit.oLanguage ); 11941 11942 // If the length menu is given, but the init display length is not, use the length menu 11943 if ( oInit.aLengthMenu && ! oInit.iDisplayLength ) 11944 { 11945 oInit.iDisplayLength = Array.isArray( oInit.aLengthMenu[0] ) ? 11946 oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0]; 11947 } 11948 11949 // Apply the defaults and init options to make a single init object will all 11950 // options defined from defaults and instance options. 11951 oInit = _fnExtend( $.extend( true, {}, defaults ), oInit ); 11952 11953 11954 // Map the initialisation options onto the settings object 11955 _fnMap( oSettings.oFeatures, oInit, [ 11956 "bPaginate", 11957 "bLengthChange", 11958 "bFilter", 11959 "bSort", 11960 "bSortMulti", 11961 "bInfo", 11962 "bProcessing", 11963 "bAutoWidth", 11964 "bSortClasses", 11965 "bServerSide", 11966 "bDeferRender" 11967 ] ); 11968 _fnMap( oSettings, oInit, [ 11969 "asStripeClasses", 11970 "ajax", 11971 "fnServerData", 11972 "fnFormatNumber", 11973 "sServerMethod", 11974 "aaSorting", 11975 "aaSortingFixed", 11976 "aLengthMenu", 11977 "sPaginationType", 11978 "sAjaxSource", 11979 "sAjaxDataProp", 11980 "iStateDuration", 11981 "sDom", 11982 "bSortCellsTop", 11983 "iTabIndex", 11984 "fnStateLoadCallback", 11985 "fnStateSaveCallback", 11986 "renderer", 11987 "searchDelay", 11988 "rowId", 11989 [ "iCookieDuration", "iStateDuration" ], // backwards compat 11990 [ "oSearch", "oPreviousSearch" ], 11991 [ "aoSearchCols", "aoPreSearchCols" ], 11992 [ "iDisplayLength", "_iDisplayLength" ] 11993 ] ); 11994 _fnMap( oSettings.oScroll, oInit, [ 11995 [ "sScrollX", "sX" ], 11996 [ "sScrollXInner", "sXInner" ], 11997 [ "sScrollY", "sY" ], 11998 [ "bScrollCollapse", "bCollapse" ] 11999 ] ); 12000 _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); 12001 12002 /* Callback functions which are array driven */ 12003 _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' ); 12004 _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' ); 12005 _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' ); 12006 _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' ); 12007 _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' ); 12008 _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' ); 12009 _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' ); 12010 _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' ); 12011 _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' ); 12012 _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' ); 12013 _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' ); 12014 12015 oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId ); 12016 12017 /* Browser support detection */ 12018 _fnBrowserDetect( oSettings ); 12019 12020 var oClasses = oSettings.oClasses; 12021 12022 $.extend( oClasses, DataTable.ext.classes, oInit.oClasses ); 12023 $this.addClass( oClasses.sTable ); 12024 12025 12026 if ( oSettings.iInitDisplayStart === undefined ) 12027 { 12028 /* Display start point, taking into account the save saving */ 12029 oSettings.iInitDisplayStart = oInit.iDisplayStart; 12030 oSettings._iDisplayStart = oInit.iDisplayStart; 12031 } 12032 12033 if ( oInit.iDeferLoading !== null ) 12034 { 12035 oSettings.bDeferLoading = true; 12036 var tmp = Array.isArray( oInit.iDeferLoading ); 12037 oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading; 12038 oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading; 12039 } 12040 12041 /* Language definitions */ 12042 var oLanguage = oSettings.oLanguage; 12043 $.extend( true, oLanguage, oInit.oLanguage ); 12044 12045 if ( oLanguage.sUrl ) 12046 { 12047 /* Get the language definitions from a file - because this Ajax call makes the language 12048 * get async to the remainder of this function we use bInitHandedOff to indicate that 12049 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor 12050 */ 12051 $.ajax( { 12052 dataType: 'json', 12053 url: oLanguage.sUrl, 12054 success: function ( json ) { 12055 _fnCamelToHungarian( defaults.oLanguage, json ); 12056 _fnLanguageCompat( json ); 12057 $.extend( true, oLanguage, json ); 12058 12059 _fnCallbackFire( oSettings, null, 'i18n', [oSettings]); 12060 _fnInitialise( oSettings ); 12061 }, 12062 error: function () { 12063 // Error occurred loading language file, continue on as best we can 12064 _fnInitialise( oSettings ); 12065 } 12066 } ); 12067 bInitHandedOff = true; 12068 } 12069 else { 12070 _fnCallbackFire( oSettings, null, 'i18n', [oSettings]); 12071 } 12072 12073 /* 12074 * Stripes 12075 */ 12076 if ( oInit.asStripeClasses === null ) 12077 { 12078 oSettings.asStripeClasses =[ 12079 oClasses.sStripeOdd, 12080 oClasses.sStripeEven 12081 ]; 12082 } 12083 12084 /* Remove row stripe classes if they are already on the table row */ 12085 var stripeClasses = oSettings.asStripeClasses; 12086 var rowOne = $this.children('tbody').find('tr').eq(0); 12087 if ( $.inArray( true, $.map( stripeClasses, function(el, i) { 12088 return rowOne.hasClass(el); 12089 } ) ) !== -1 ) { 12090 $('tbody tr', this).removeClass( stripeClasses.join(' ') ); 12091 oSettings.asDestroyStripes = stripeClasses.slice(); 12092 } 12093 12094 /* 12095 * Columns 12096 * See if we should load columns automatically or use defined ones 12097 */ 12098 var anThs = []; 12099 var aoColumnsInit; 12100 var nThead = this.getElementsByTagName('thead'); 12101 if ( nThead.length !== 0 ) 12102 { 12103 _fnDetectHeader( oSettings.aoHeader, nThead[0] ); 12104 anThs = _fnGetUniqueThs( oSettings ); 12105 } 12106 12107 /* If not given a column array, generate one with nulls */ 12108 if ( oInit.aoColumns === null ) 12109 { 12110 aoColumnsInit = []; 12111 for ( i=0, iLen=anThs.length ; i<iLen ; i++ ) 12112 { 12113 aoColumnsInit.push( null ); 12114 } 12115 } 12116 else 12117 { 12118 aoColumnsInit = oInit.aoColumns; 12119 } 12120 12121 /* Add the columns */ 12122 for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ ) 12123 { 12124 _fnAddColumn( oSettings, anThs ? anThs[i] : null ); 12125 } 12126 12127 /* Apply the column definitions */ 12128 _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) { 12129 _fnColumnOptions( oSettings, iCol, oDef ); 12130 } ); 12131 12132 /* HTML5 attribute detection - build an mData object automatically if the 12133 * attributes are found 12134 */ 12135 if ( rowOne.length ) { 12136 var a = function ( cell, name ) { 12137 return cell.getAttribute( 'data-'+name ) !== null ? name : null; 12138 }; 12139 12140 $( rowOne[0] ).children('th, td').each( function (i, cell) { 12141 var col = oSettings.aoColumns[i]; 12142 12143 if ( col.mData === i ) { 12144 var sort = a( cell, 'sort' ) || a( cell, 'order' ); 12145 var filter = a( cell, 'filter' ) || a( cell, 'search' ); 12146 12147 if ( sort !== null || filter !== null ) { 12148 col.mData = { 12149 _: i+'.display', 12150 sort: sort !== null ? i+'.@data-'+sort : undefined, 12151 type: sort !== null ? i+'.@data-'+sort : undefined, 12152 filter: filter !== null ? i+'.@data-'+filter : undefined 12153 }; 12154 12155 _fnColumnOptions( oSettings, i ); 12156 } 12157 } 12158 } ); 12159 } 12160 12161 var features = oSettings.oFeatures; 12162 var loadedInit = function () { 12163 /* 12164 * Sorting 12165 * @todo For modularisation (1.11) this needs to do into a sort start up handler 12166 */ 12167 12168 // If aaSorting is not defined, then we use the first indicator in asSorting 12169 // in case that has been altered, so the default sort reflects that option 12170 if ( oInit.aaSorting === undefined ) { 12171 var sorting = oSettings.aaSorting; 12172 for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) { 12173 sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0]; 12174 } 12175 } 12176 12177 /* Do a first pass on the sorting classes (allows any size changes to be taken into 12178 * account, and also will apply sorting disabled classes if disabled 12179 */ 12180 _fnSortingClasses( oSettings ); 12181 12182 if ( features.bSort ) { 12183 _fnCallbackReg( oSettings, 'aoDrawCallback', function () { 12184 if ( oSettings.bSorted ) { 12185 var aSort = _fnSortFlatten( oSettings ); 12186 var sortedColumns = {}; 12187 12188 $.each( aSort, function (i, val) { 12189 sortedColumns[ val.src ] = val.dir; 12190 } ); 12191 12192 _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] ); 12193 _fnSortAria( oSettings ); 12194 } 12195 } ); 12196 } 12197 12198 _fnCallbackReg( oSettings, 'aoDrawCallback', function () { 12199 if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) { 12200 _fnSortingClasses( oSettings ); 12201 } 12202 }, 'sc' ); 12203 12204 12205 /* 12206 * Final init 12207 * Cache the header, body and footer as required, creating them if needed 12208 */ 12209 12210 // Work around for Webkit bug 83867 - store the caption-side before removing from doc 12211 var captions = $this.children('caption').each( function () { 12212 this._captionSide = $(this).css('caption-side'); 12213 } ); 12214 12215 var thead = $this.children('thead'); 12216 if ( thead.length === 0 ) { 12217 thead = $('<thead/>').appendTo($this); 12218 } 12219 oSettings.nTHead = thead[0]; 12220 12221 var tbody = $this.children('tbody'); 12222 if ( tbody.length === 0 ) { 12223 tbody = $('<tbody/>').insertAfter(thead); 12224 } 12225 oSettings.nTBody = tbody[0]; 12226 12227 var tfoot = $this.children('tfoot'); 12228 if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) { 12229 // If we are a scrolling table, and no footer has been given, then we need to create 12230 // a tfoot element for the caption element to be appended to 12231 tfoot = $('<tfoot/>').appendTo($this); 12232 } 12233 12234 if ( tfoot.length === 0 || tfoot.children().length === 0 ) { 12235 $this.addClass( oClasses.sNoFooter ); 12236 } 12237 else if ( tfoot.length > 0 ) { 12238 oSettings.nTFoot = tfoot[0]; 12239 _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot ); 12240 } 12241 12242 /* Check if there is data passing into the constructor */ 12243 if ( oInit.aaData ) { 12244 for ( i=0 ; i<oInit.aaData.length ; i++ ) { 12245 _fnAddData( oSettings, oInit.aaData[ i ] ); 12246 } 12247 } 12248 else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) { 12249 /* Grab the data from the page - only do this when deferred loading or no Ajax 12250 * source since there is no point in reading the DOM data if we are then going 12251 * to replace it with Ajax data 12252 */ 12253 _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') ); 12254 } 12255 12256 /* Copy the data index array */ 12257 oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); 12258 12259 /* Initialisation complete - table can be drawn */ 12260 oSettings.bInitialised = true; 12261 12262 /* Check if we need to initialise the table (it might not have been handed off to the 12263 * language processor) 12264 */ 12265 if ( bInitHandedOff === false ) { 12266 _fnInitialise( oSettings ); 12267 } 12268 }; 12269 12270 /* Must be done after everything which can be overridden by the state saving! */ 12271 _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' ); 12272 12273 if ( oInit.bStateSave ) 12274 { 12275 features.bStateSave = true; 12276 _fnLoadState( oSettings, oInit, loadedInit ); 12277 } 12278 else { 12279 loadedInit(); 12280 } 12281 12282 } ); 12283 _that = null; 12284 return this; 12285 }; 12286 12287 12288 /* 12289 * It is useful to have variables which are scoped locally so only the 12290 * DataTables functions can access them and they don't leak into global space. 12291 * At the same time these functions are often useful over multiple files in the 12292 * core and API, so we list, or at least document, all variables which are used 12293 * by DataTables as private variables here. This also ensures that there is no 12294 * clashing of variable names and that they can easily referenced for reuse. 12295 */ 12296 12297 12298 // Defined else where 12299 // _selector_run 12300 // _selector_opts 12301 // _selector_first 12302 // _selector_row_indexes 12303 12304 var _ext; // DataTable.ext 12305 var _Api; // DataTable.Api 12306 var _api_register; // DataTable.Api.register 12307 var _api_registerPlural; // DataTable.Api.registerPlural 12308 12309 var _re_dic = {}; 12310 var _re_new_lines = /[\r\n\u2028]/g; 12311 var _re_html = /<.*?>/g; 12312 12313 // This is not strict ISO8601 - Date.parse() is quite lax, although 12314 // implementations differ between browsers. 12315 var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/; 12316 12317 // Escape regular expression special characters 12318 var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); 12319 12320 // http://en.wikipedia.org/wiki/Foreign_exchange_market 12321 // - \u20BD - Russian ruble. 12322 // - \u20a9 - South Korean Won 12323 // - \u20BA - Turkish Lira 12324 // - \u20B9 - Indian Rupee 12325 // - R - Brazil (R$) and South Africa 12326 // - fr - Swiss Franc 12327 // - kr - Swedish krona, Norwegian krone and Danish krone 12328 // - \u2009 is thin space and \u202F is narrow no-break space, both used in many 12329 // - É - Bitcoin 12330 // - Î - Ethereum 12331 // standards as thousands separators. 12332 var _re_formatted_numeric = /['\u00A0,$£â¬Â¥%\u2009\u202F\u20BD\u20a9\u20BArfkÉÎ]/gi; 12333 12334 12335 var _empty = function ( d ) { 12336 return !d || d === true || d === '-' ? true : false; 12337 }; 12338 12339 12340 var _intVal = function ( s ) { 12341 var integer = parseInt( s, 10 ); 12342 return !isNaN(integer) && isFinite(s) ? integer : null; 12343 }; 12344 12345 // Convert from a formatted number with characters other than `.` as the 12346 // decimal place, to a Javascript number 12347 var _numToDecimal = function ( num, decimalPoint ) { 12348 // Cache created regular expressions for speed as this function is called often 12349 if ( ! _re_dic[ decimalPoint ] ) { 12350 _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); 12351 } 12352 return typeof num === 'string' && decimalPoint !== '.' ? 12353 num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : 12354 num; 12355 }; 12356 12357 12358 var _isNumber = function ( d, decimalPoint, formatted ) { 12359 var strType = typeof d === 'string'; 12360 12361 // If empty return immediately so there must be a number if it is a 12362 // formatted string (this stops the string "k", or "kr", etc being detected 12363 // as a formatted number for currency 12364 if ( _empty( d ) ) { 12365 return true; 12366 } 12367 12368 if ( decimalPoint && strType ) { 12369 d = _numToDecimal( d, decimalPoint ); 12370 } 12371 12372 if ( formatted && strType ) { 12373 d = d.replace( _re_formatted_numeric, '' ); 12374 } 12375 12376 return !isNaN( parseFloat(d) ) && isFinite( d ); 12377 }; 12378 12379 12380 // A string without HTML in it can be considered to be HTML still 12381 var _isHtml = function ( d ) { 12382 return _empty( d ) || typeof d === 'string'; 12383 }; 12384 12385 12386 var _htmlNumeric = function ( d, decimalPoint, formatted ) { 12387 if ( _empty( d ) ) { 12388 return true; 12389 } 12390 12391 var html = _isHtml( d ); 12392 return ! html ? 12393 null : 12394 _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? 12395 true : 12396 null; 12397 }; 12398 12399 12400 var _pluck = function ( a, prop, prop2 ) { 12401 var out = []; 12402 var i=0, ien=a.length; 12403 12404 // Could have the test in the loop for slightly smaller code, but speed 12405 // is essential here 12406 if ( prop2 !== undefined ) { 12407 for ( ; i<ien ; i++ ) { 12408 if ( a[i] && a[i][ prop ] ) { 12409 out.push( a[i][ prop ][ prop2 ] ); 12410 } 12411 } 12412 } 12413 else { 12414 for ( ; i<ien ; i++ ) { 12415 if ( a[i] ) { 12416 out.push( a[i][ prop ] ); 12417 } 12418 } 12419 } 12420 12421 return out; 12422 }; 12423 12424 12425 // Basically the same as _pluck, but rather than looping over `a` we use `order` 12426 // as the indexes to pick from `a` 12427 var _pluck_order = function ( a, order, prop, prop2 ) 12428 { 12429 var out = []; 12430 var i=0, ien=order.length; 12431 12432 // Could have the test in the loop for slightly smaller code, but speed 12433 // is essential here 12434 if ( prop2 !== undefined ) { 12435 for ( ; i<ien ; i++ ) { 12436 if ( a[ order[i] ][ prop ] ) { 12437 out.push( a[ order[i] ][ prop ][ prop2 ] ); 12438 } 12439 } 12440 } 12441 else { 12442 for ( ; i<ien ; i++ ) { 12443 out.push( a[ order[i] ][ prop ] ); 12444 } 12445 } 12446 12447 return out; 12448 }; 12449 12450 12451 var _range = function ( len, start ) 12452 { 12453 var out = []; 12454 var end; 12455 12456 if ( start === undefined ) { 12457 start = 0; 12458 end = len; 12459 } 12460 else { 12461 end = start; 12462 start = len; 12463 } 12464 12465 for ( var i=start ; i<end ; i++ ) { 12466 out.push( i ); 12467 } 12468 12469 return out; 12470 }; 12471 12472 12473 var _removeEmpty = function ( a ) 12474 { 12475 var out = []; 12476 12477 for ( var i=0, ien=a.length ; i<ien ; i++ ) { 12478 if ( a[i] ) { // careful - will remove all falsy values! 12479 out.push( a[i] ); 12480 } 12481 } 12482 12483 return out; 12484 }; 12485 12486 12487 var _stripHtml = function ( d ) { 12488 return d.replace( _re_html, '' );
vendor: 10,574 bytes, lines 12488-12862
12488 12489 }; 12490 12491 12492 /** 12493 * Determine if all values in the array are unique. This means we can short 12494 * cut the _unique method at the cost of a single loop. A sorted array is used 12495 * to easily check the values. 12496 * 12497 * @param {array} src Source array 12498 * @return {boolean} true if all unique, false otherwise 12499 * @ignore 12500 */ 12501 var _areAllUnique = function ( src ) { 12502 if ( src.length < 2 ) { 12503 return true; 12504 } 12505 12506 var sorted = src.slice().sort(); 12507 var last = sorted[0]; 12508 12509 for ( var i=1, ien=sorted.length ; i<ien ; i++ ) { 12510 if ( sorted[i] === last ) { 12511 return false; 12512 } 12513 12514 last = sorted[i]; 12515 } 12516 12517 return true; 12518 }; 12519 12520 12521 /** 12522 * Find the unique elements in a source array. 12523 * 12524 * @param {array} src Source array 12525 * @return {array} Array of unique items 12526 * @ignore 12527 */ 12528 var _unique = function ( src ) 12529 { 12530 if ( _areAllUnique( src ) ) { 12531 return src.slice(); 12532 } 12533 12534 // A faster unique method is to use object keys to identify used values, 12535 // but this doesn't work with arrays or objects, which we must also 12536 // consider. See jsperf.com/compare-array-unique-versions/4 for more 12537 // information. 12538 var 12539 out = [], 12540 val, 12541 i, ien=src.length, 12542 j, k=0; 12543 12544 again: for ( i=0 ; i<ien ; i++ ) { 12545 val = src[i]; 12546 12547 for ( j=0 ; j<k ; j++ ) { 12548 if ( out[j] === val ) { 12549 continue again; 12550 } 12551 } 12552 12553 out.push( val ); 12554 k++; 12555 } 12556 12557 return out; 12558 }; 12559 12560 // Surprisingly this is faster than [].concat.apply 12561 // https://jsperf.com/flatten-an-array-loop-vs-reduce/2 12562 var _flatten = function (out, val) { 12563 if (Array.isArray(val)) { 12564 for (var i=0 ; i<val.length ; i++) { 12565 _flatten(out, val[i]); 12566 } 12567 } 12568 else { 12569 out.push(val); 12570 } 12571 12572 return out; 12573 } 12574 12575 var _includes = function (search, start) { 12576 if (start === undefined) { 12577 start = 0; 12578 } 12579 12580 return this.indexOf(search, start) !== -1; 12581 }; 12582 12583 // Array.isArray polyfill. 12584 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray 12585 if (! Array.isArray) { 12586 Array.isArray = function(arg) { 12587 return Object.prototype.toString.call(arg) === '[object Array]'; 12588 }; 12589 } 12590 12591 if (! Array.prototype.includes) { 12592 Array.prototype.includes = _includes; 12593 } 12594 12595 // .trim() polyfill 12596 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim 12597 if (!String.prototype.trim) { 12598 String.prototype.trim = function () { 12599 return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); 12600 }; 12601 } 12602 12603 if (! String.prototype.includes) { 12604 String.prototype.includes = _includes; 12605 } 12606 12607 /** 12608 * DataTables utility methods 12609 * 12610 * This namespace provides helper methods that DataTables uses internally to 12611 * create a DataTable, but which are not exclusively used only for DataTables. 12612 * These methods can be used by extension authors to save the duplication of 12613 * code. 12614 * 12615 * @namespace 12616 */ 12617 DataTable.util = { 12618 /** 12619 * Throttle the calls to a function. Arguments and context are maintained 12620 * for the throttled function. 12621 * 12622 * @param {function} fn Function to be called 12623 * @param {integer} freq Call frequency in mS 12624 * @return {function} Wrapped function 12625 */ 12626 throttle: function ( fn, freq ) { 12627 var 12628 frequency = freq !== undefined ? freq : 200, 12629 last, 12630 timer; 12631 12632 return function () { 12633 var 12634 that = this, 12635 now = +new Date(), 12636 args = arguments; 12637 12638 if ( last && now < last + frequency ) { 12639 clearTimeout( timer ); 12640 12641 timer = setTimeout( function () { 12642 last = undefined; 12643 fn.apply( that, args ); 12644 }, frequency ); 12645 } 12646 else { 12647 last = now; 12648 fn.apply( that, args ); 12649 } 12650 }; 12651 }, 12652 12653 12654 /** 12655 * Escape a string such that it can be used in a regular expression 12656 * 12657 * @param {string} val string to escape 12658 * @returns {string} escaped string 12659 */ 12660 escapeRegex: function ( val ) { 12661 return val.replace( _re_escape_regex, '\\$1' ); 12662 }, 12663 12664 /** 12665 * Create a function that will write to a nested object or array 12666 * @param {*} source JSON notation string 12667 * @returns Write function 12668 */ 12669 set: function ( source ) { 12670 if ( $.isPlainObject( source ) ) { 12671 /* Unlike get, only the underscore (global) option is used for for 12672 * setting data since we don't know the type here. This is why an object 12673 * option is not documented for `mData` (which is read/write), but it is 12674 * for `mRender` which is read only. 12675 */ 12676 return DataTable.util.set( source._ ); 12677 } 12678 else if ( source === null ) { 12679 // Nothing to do when the data source is null 12680 return function () {}; 12681 } 12682 else if ( typeof source === 'function' ) { 12683 return function (data, val, meta) { 12684 source( data, 'set', val, meta ); 12685 }; 12686 } 12687 else if ( typeof source === 'string' && (source.indexOf('.') !== -1 || 12688 source.indexOf('[') !== -1 || source.indexOf('(') !== -1) ) 12689 { 12690 // Like the get, we need to get data from a nested object 12691 var setData = function (data, val, src) { 12692 var a = _fnSplitObjNotation( src ), b; 12693 var aLast = a[a.length-1]; 12694 var arrayNotation, funcNotation, o, innerSrc; 12695 12696 for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) { 12697 // Protect against prototype pollution 12698 if (a[i] === '__proto__' || a[i] === 'constructor') { 12699 throw new Error('Cannot set prototype values'); 12700 } 12701 12702 // Check if we are dealing with an array notation request 12703 arrayNotation = a[i].match(__reArray); 12704 funcNotation = a[i].match(__reFn); 12705 12706 if ( arrayNotation ) { 12707 a[i] = a[i].replace(__reArray, ''); 12708 data[ a[i] ] = []; 12709 12710 // Get the remainder of the nested object to set so we can recurse 12711 b = a.slice(); 12712 b.splice( 0, i+1 ); 12713 innerSrc = b.join('.'); 12714 12715 // Traverse each entry in the array setting the properties requested 12716 if ( Array.isArray( val ) ) { 12717 for ( var j=0, jLen=val.length ; j<jLen ; j++ ) { 12718 o = {}; 12719 setData( o, val[j], innerSrc ); 12720 data[ a[i] ].push( o ); 12721 } 12722 } 12723 else { 12724 // We've been asked to save data to an array, but it 12725 // isn't array data to be saved. Best that can be done 12726 // is to just save the value. 12727 data[ a[i] ] = val; 12728 } 12729 12730 // The inner call to setData has already traversed through the remainder 12731 // of the source and has set the data, thus we can exit here 12732 return; 12733 } 12734 else if ( funcNotation ) { 12735 // Function call 12736 a[i] = a[i].replace(__reFn, ''); 12737 data = data[ a[i] ]( val ); 12738 } 12739 12740 // If the nested object doesn't currently exist - since we are 12741 // trying to set the value - create it 12742 if ( data[ a[i] ] === null || data[ a[i] ] === undefined ) { 12743 data[ a[i] ] = {}; 12744 } 12745 data = data[ a[i] ]; 12746 } 12747 12748 // Last item in the input - i.e, the actual set 12749 if ( aLast.match(__reFn ) ) { 12750 // Function call 12751 data = data[ aLast.replace(__reFn, '') ]( val ); 12752 } 12753 else { 12754 // If array notation is used, we just want to strip it and use the property name 12755 // and assign the value. If it isn't used, then we get the result we want anyway 12756 data[ aLast.replace(__reArray, '') ] = val; 12757 } 12758 }; 12759 12760 return function (data, val) { // meta is also passed in, but not used 12761 return setData( data, val, source ); 12762 }; 12763 } 12764 else { 12765 // Array or flat object mapping 12766 return function (data, val) { // meta is also passed in, but not used 12767 data[source] = val; 12768 }; 12769 } 12770 }, 12771 12772 /** 12773 * Create a function that will read nested objects from arrays, based on JSON notation 12774 * @param {*} source JSON notation string 12775 * @returns Value read 12776 */ 12777 get: function ( source ) { 12778 if ( $.isPlainObject( source ) ) { 12779 // Build an object of get functions, and wrap them in a single call 12780 var o = {}; 12781 $.each( source, function (key, val) { 12782 if ( val ) { 12783 o[key] = DataTable.util.get( val ); 12784 } 12785 } ); 12786 12787 return function (data, type, row, meta) { 12788 var t = o[type] || o._; 12789 return t !== undefined ? 12790 t(data, type, row, meta) : 12791 data; 12792 }; 12793 } 12794 else if ( source === null ) { 12795 // Give an empty string for rendering / sorting etc 12796 return function (data) { // type, row and meta also passed, but not used 12797 return data; 12798 }; 12799 } 12800 else if ( typeof source === 'function' ) { 12801 return function (data, type, row, meta) { 12802 return source( data, type, row, meta ); 12803 }; 12804 } 12805 else if ( typeof source === 'string' && (source.indexOf('.') !== -1 || 12806 source.indexOf('[') !== -1 || source.indexOf('(') !== -1) ) 12807 { 12808 /* If there is a . in the source string then the data source is in a 12809 * nested object so we loop over the data for each level to get the next 12810 * level down. On each loop we test for undefined, and if found immediately 12811 * return. This allows entire objects to be missing and sDefaultContent to 12812 * be used if defined, rather than throwing an error 12813 */ 12814 var fetchData = function (data, type, src) { 12815 var arrayNotation, funcNotation, out, innerSrc; 12816 12817 if ( src !== "" ) { 12818 var a = _fnSplitObjNotation( src ); 12819 12820 for ( var i=0, iLen=a.length ; i<iLen ; i++ ) { 12821 // Check if we are dealing with special notation 12822 arrayNotation = a[i].match(__reArray); 12823 funcNotation = a[i].match(__reFn); 12824 12825 if ( arrayNotation ) { 12826 // Array notation 12827 a[i] = a[i].replace(__reArray, ''); 12828 12829 // Condition allows simply [] to be passed in 12830 if ( a[i] !== "" ) { 12831 data = data[ a[i] ]; 12832 } 12833 out = []; 12834 12835 // Get the remainder of the nested object to get 12836 a.splice( 0, i+1 ); 12837 innerSrc = a.join('.'); 12838 12839 // Traverse each entry in the array getting the properties requested 12840 if ( Array.isArray( data ) ) { 12841 for ( var j=0, jLen=data.length ; j<jLen ; j++ ) { 12842 out.push( fetchData( data[j], type, innerSrc ) ); 12843 } 12844 } 12845 12846 // If a string is given in between the array notation indicators, that 12847 // is used to join the strings together, otherwise an array is returned 12848 var join = arrayNotation[0].substring(1, arrayNotation[0].length-1); 12849 data = (join==="") ? out : out.join(join); 12850 12851 // The inner call to fetchData has already traversed through the remainder 12852 // of the source requested, so we exit from the loop 12853 break; 12854 } 12855 else if ( funcNotation ) { 12856 // Function call 12857 a[i] = a[i].replace(__reFn, ''); 12858 data = data[ a[i] ](); 12859 continue; 12860 } 12861 12862 if (
vendor: 20,462 bytes, lines 12862-13567
12862 data === null || data[ a[i] ] === undefined ) { 12863 return undefined; 12864 } 12865 12866 data = data[ a[i] ]; 12867 } 12868 } 12869 12870 return data; 12871 }; 12872 12873 return function (data, type) { // row and meta also passed, but not used 12874 return fetchData( data, type, source ); 12875 }; 12876 } 12877 else { 12878 // Array or flat object mapping 12879 return function (data, type) { // row and meta also passed, but not used 12880 return data[source]; 12881 }; 12882 } 12883 } 12884 }; 12885 12886 12887 12888 /** 12889 * Create a mapping object that allows camel case parameters to be looked up 12890 * for their Hungarian counterparts. The mapping is stored in a private 12891 * parameter called `_hungarianMap` which can be accessed on the source object. 12892 * @param {object} o 12893 * @memberof DataTable#oApi 12894 */ 12895 function _fnHungarianMap ( o ) 12896 { 12897 var 12898 hungarian = 'a aa ai ao as b fn i m o s ', 12899 match, 12900 newKey, 12901 map = {}; 12902 12903 $.each( o, function (key, val) { 12904 match = key.match(/^([^A-Z]+?)([A-Z])/); 12905 12906 if ( match && hungarian.indexOf(match[1]+' ') !== -1 ) 12907 { 12908 newKey = key.replace( match[0], match[2].toLowerCase() ); 12909 map[ newKey ] = key; 12910 12911 if ( match[1] === 'o' ) 12912 { 12913 _fnHungarianMap( o[key] ); 12914 } 12915 } 12916 } ); 12917 12918 o._hungarianMap = map; 12919 } 12920 12921 12922 /** 12923 * Convert from camel case parameters to Hungarian, based on a Hungarian map 12924 * created by _fnHungarianMap. 12925 * @param {object} src The model object which holds all parameters that can be 12926 * mapped. 12927 * @param {object} user The object to convert from camel case to Hungarian. 12928 * @param {boolean} force When set to `true`, properties which already have a 12929 * Hungarian value in the `user` object will be overwritten. Otherwise they 12930 * won't be. 12931 * @memberof DataTable#oApi 12932 */ 12933 function _fnCamelToHungarian ( src, user, force ) 12934 { 12935 if ( ! src._hungarianMap ) { 12936 _fnHungarianMap( src ); 12937 } 12938 12939 var hungarianKey; 12940 12941 $.each( user, function (key, val) { 12942 hungarianKey = src._hungarianMap[ key ]; 12943 12944 if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) ) 12945 { 12946 // For objects, we need to buzz down into the object to copy parameters 12947 if ( hungarianKey.charAt(0) === 'o' ) 12948 { 12949 // Copy the camelCase options over to the hungarian 12950 if ( ! user[ hungarianKey ] ) { 12951 user[ hungarianKey ] = {}; 12952 } 12953 $.extend( true, user[hungarianKey], user[key] ); 12954 12955 _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force ); 12956 } 12957 else { 12958 user[hungarianKey] = user[ key ]; 12959 } 12960 } 12961 } ); 12962 } 12963 12964 12965 /** 12966 * Language compatibility - when certain options are given, and others aren't, we 12967 * need to duplicate the values over, in order to provide backwards compatibility 12968 * with older language files. 12969 * @param {object} oSettings dataTables settings object 12970 * @memberof DataTable#oApi 12971 */ 12972 function _fnLanguageCompat( lang ) 12973 { 12974 // Note the use of the Hungarian notation for the parameters in this method as 12975 // this is called after the mapping of camelCase to Hungarian 12976 var defaults = DataTable.defaults.oLanguage; 12977 12978 // Default mapping 12979 var defaultDecimal = defaults.sDecimal; 12980 if ( defaultDecimal ) { 12981 _addNumericSort( defaultDecimal ); 12982 } 12983 12984 if ( lang ) { 12985 var zeroRecords = lang.sZeroRecords; 12986 12987 // Backwards compatibility - if there is no sEmptyTable given, then use the same as 12988 // sZeroRecords - assuming that is given. 12989 if ( ! lang.sEmptyTable && zeroRecords && 12990 defaults.sEmptyTable === "No data available in table" ) 12991 { 12992 _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' ); 12993 } 12994 12995 // Likewise with loading records 12996 if ( ! lang.sLoadingRecords && zeroRecords && 12997 defaults.sLoadingRecords === "Loading..." ) 12998 { 12999 _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' ); 13000 } 13001 13002 // Old parameter name of the thousands separator mapped onto the new 13003 if ( lang.sInfoThousands ) { 13004 lang.sThousands = lang.sInfoThousands; 13005 } 13006 13007 var decimal = lang.sDecimal; 13008 if ( decimal && defaultDecimal !== decimal ) { 13009 _addNumericSort( decimal ); 13010 } 13011 } 13012 } 13013 13014 13015 /** 13016 * Map one parameter onto another 13017 * @param {object} o Object to map 13018 * @param {*} knew The new parameter name 13019 * @param {*} old The old parameter name 13020 */ 13021 var _fnCompatMap = function ( o, knew, old ) { 13022 if ( o[ knew ] !== undefined ) { 13023 o[ old ] = o[ knew ]; 13024 } 13025 }; 13026 13027 13028 /** 13029 * Provide backwards compatibility for the main DT options. Note that the new 13030 * options are mapped onto the old parameters, so this is an external interface 13031 * change only. 13032 * @param {object} init Object to map 13033 */ 13034 function _fnCompatOpts ( init ) 13035 { 13036 _fnCompatMap( init, 'ordering', 'bSort' ); 13037 _fnCompatMap( init, 'orderMulti', 'bSortMulti' ); 13038 _fnCompatMap( init, 'orderClasses', 'bSortClasses' ); 13039 _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' ); 13040 _fnCompatMap( init, 'order', 'aaSorting' ); 13041 _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' ); 13042 _fnCompatMap( init, 'paging', 'bPaginate' ); 13043 _fnCompatMap( init, 'pagingType', 'sPaginationType' ); 13044 _fnCompatMap( init, 'pageLength', 'iDisplayLength' ); 13045 _fnCompatMap( init, 'searching', 'bFilter' ); 13046 13047 // Boolean initialisation of x-scrolling 13048 if ( typeof init.sScrollX === 'boolean' ) { 13049 init.sScrollX = init.sScrollX ? '100%' : ''; 13050 } 13051 if ( typeof init.scrollX === 'boolean' ) { 13052 init.scrollX = init.scrollX ? '100%' : ''; 13053 } 13054 13055 // Column search objects are in an array, so it needs to be converted 13056 // element by element 13057 var searchCols = init.aoSearchCols; 13058 13059 if ( searchCols ) { 13060 for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) { 13061 if ( searchCols[i] ) { 13062 _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] ); 13063 } 13064 } 13065 } 13066 } 13067 13068 13069 /** 13070 * Provide backwards compatibility for column options. Note that the new options 13071 * are mapped onto the old parameters, so this is an external interface change 13072 * only. 13073 * @param {object} init Object to map 13074 */ 13075 function _fnCompatCols ( init ) 13076 { 13077 _fnCompatMap( init, 'orderable', 'bSortable' ); 13078 _fnCompatMap( init, 'orderData', 'aDataSort' ); 13079 _fnCompatMap( init, 'orderSequence', 'asSorting' ); 13080 _fnCompatMap( init, 'orderDataType', 'sortDataType' ); 13081 13082 // orderData can be given as an integer 13083 var dataSort = init.aDataSort; 13084 if ( typeof dataSort === 'number' && ! Array.isArray( dataSort ) ) { 13085 init.aDataSort = [ dataSort ]; 13086 } 13087 } 13088 13089 13090 /** 13091 * Browser feature detection for capabilities, quirks 13092 * @param {object} settings dataTables settings object 13093 * @memberof DataTable#oApi 13094 */ 13095 function _fnBrowserDetect( settings ) 13096 { 13097 // We don't need to do this every time DataTables is constructed, the values 13098 // calculated are specific to the browser and OS configuration which we 13099 // don't expect to change between initialisations 13100 if ( ! DataTable.__browser ) { 13101 var browser = {}; 13102 DataTable.__browser = browser; 13103 13104 // Scrolling feature / quirks detection 13105 var n = $('<div/>') 13106 .css( { 13107 position: 'fixed', 13108 top: 0, 13109 left: $(window).scrollLeft()*-1, // allow for scrolling 13110 height: 1, 13111 width: 1, 13112 overflow: 'hidden' 13113 } ) 13114 .append( 13115 $('<div/>') 13116 .css( { 13117 position: 'absolute', 13118 top: 1, 13119 left: 1, 13120 width: 100, 13121 overflow: 'scroll' 13122 } ) 13123 .append( 13124 $('<div/>') 13125 .css( { 13126 width: '100%', 13127 height: 10 13128 } ) 13129 ) 13130 ) 13131 .appendTo( 'body' ); 13132 13133 var outer = n.children(); 13134 var inner = outer.children(); 13135 13136 // Numbers below, in order, are: 13137 // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth 13138 // 13139 // IE6 XP: 100 100 100 83 13140 // IE7 Vista: 100 100 100 83 13141 // IE 8+ Windows: 83 83 100 83 13142 // Evergreen Windows: 83 83 100 83 13143 // Evergreen Mac with scrollbars: 85 85 100 85 13144 // Evergreen Mac without scrollbars: 100 100 100 100 13145 13146 // Get scrollbar width 13147 browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth; 13148 13149 // IE6/7 will oversize a width 100% element inside a scrolling element, to 13150 // include the width of the scrollbar, while other browsers ensure the inner 13151 // element is contained without forcing scrolling 13152 browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100; 13153 13154 // In rtl text layout, some browsers (most, but not all) will place the 13155 // scrollbar on the left, rather than the right. 13156 browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1; 13157 13158 // IE8- don't provide height and width for getBoundingClientRect 13159 browser.bBounding = n[0].getBoundingClientRect().width ? true : false; 13160 13161 n.remove(); 13162 } 13163 13164 $.extend( settings.oBrowser, DataTable.__browser ); 13165 settings.oScroll.iBarWidth = DataTable.__browser.barWidth; 13166 } 13167 13168 13169 /** 13170 * Array.prototype reduce[Right] method, used for browsers which don't support 13171 * JS 1.6. Done this way to reduce code size, since we iterate either way 13172 * @param {object} settings dataTables settings object 13173 * @memberof DataTable#oApi 13174 */ 13175 function _fnReduce ( that, fn, init, start, end, inc ) 13176 { 13177 var 13178 i = start, 13179 value, 13180 isSet = false; 13181 13182 if ( init !== undefined ) { 13183 value = init; 13184 isSet = true; 13185 } 13186 13187 while ( i !== end ) { 13188 if ( ! that.hasOwnProperty(i) ) { 13189 continue; 13190 } 13191 13192 value = isSet ? 13193 fn( value, that[i], i, that ) : 13194 that[i]; 13195 13196 isSet = true; 13197 i += inc; 13198 } 13199 13200 return value; 13201 } 13202 13203 /** 13204 * Add a column to the list used for the table with default values 13205 * @param {object} oSettings dataTables settings object 13206 * @param {node} nTh The th element for this column 13207 * @memberof DataTable#oApi 13208 */ 13209 function _fnAddColumn( oSettings, nTh ) 13210 { 13211 // Add column to aoColumns array 13212 var oDefaults = DataTable.defaults.column; 13213 var iCol = oSettings.aoColumns.length; 13214 var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { 13215 "nTh": nTh ? nTh : document.createElement('th'), 13216 "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', 13217 "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], 13218 "mData": oDefaults.mData ? oDefaults.mData : iCol, 13219 idx: iCol 13220 } ); 13221 oSettings.aoColumns.push( oCol ); 13222 13223 // Add search object for column specific search. Note that the `searchCols[ iCol ]` 13224 // passed into extend can be undefined. This allows the user to give a default 13225 // with only some of the parameters defined, and also not give a default 13226 var searchCols = oSettings.aoPreSearchCols; 13227 searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); 13228 13229 // Use the default column options function to initialise classes etc 13230 _fnColumnOptions( oSettings, iCol, $(nTh).data() ); 13231 } 13232 13233 13234 /** 13235 * Apply options for a column 13236 * @param {object} oSettings dataTables settings object 13237 * @param {int} iCol column index to consider 13238 * @param {object} oOptions object with sType, bVisible and bSearchable etc 13239 * @memberof DataTable#oApi 13240 */ 13241 function _fnColumnOptions( oSettings, iCol, oOptions ) 13242 { 13243 var oCol = oSettings.aoColumns[ iCol ]; 13244 var oClasses = oSettings.oClasses; 13245 var th = $(oCol.nTh); 13246 13247 // Try to get width information from the DOM. We can't get it from CSS 13248 // as we'd need to parse the CSS stylesheet. `width` option can override 13249 if ( ! oCol.sWidthOrig ) { 13250 // Width attribute 13251 oCol.sWidthOrig = th.attr('width') || null; 13252 13253 // Style attribute 13254 var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); 13255 if ( t ) { 13256 oCol.sWidthOrig = t[1]; 13257 } 13258 } 13259 13260 /* User specified column options */ 13261 if ( oOptions !== undefined && oOptions !== null ) 13262 { 13263 // Backwards compatibility 13264 _fnCompatCols( oOptions ); 13265 13266 // Map camel case parameters to their Hungarian counterparts 13267 _fnCamelToHungarian( DataTable.defaults.column, oOptions, true ); 13268 13269 /* Backwards compatibility for mDataProp */ 13270 if ( oOptions.mDataProp !== undefined && !oOptions.mData ) 13271 { 13272 oOptions.mData = oOptions.mDataProp; 13273 } 13274 13275 if ( oOptions.sType ) 13276 { 13277 oCol._sManualType = oOptions.sType; 13278 } 13279 13280 // `class` is a reserved word in Javascript, so we need to provide 13281 // the ability to use a valid name for the camel case input 13282 if ( oOptions.className && ! oOptions.sClass ) 13283 { 13284 oOptions.sClass = oOptions.className; 13285 } 13286 if ( oOptions.sClass ) { 13287 th.addClass( oOptions.sClass ); 13288 } 13289 13290 $.extend( oCol, oOptions ); 13291 _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); 13292 13293 /* iDataSort to be applied (backwards compatibility), but aDataSort will take 13294 * priority if defined 13295 */ 13296 if ( oOptions.iDataSort !== undefined ) 13297 { 13298 oCol.aDataSort = [ oOptions.iDataSort ]; 13299 } 13300 _fnMap( oCol, oOptions, "aDataSort" ); 13301 } 13302 13303 /* Cache the data get and set functions for speed */ 13304 var mDataSrc = oCol.mData; 13305 var mData = _fnGetObjectDataFn( mDataSrc ); 13306 var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; 13307 13308 var attrTest = function( src ) { 13309 return typeof src === 'string' && src.indexOf('@') !== -1; 13310 }; 13311 oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( 13312 attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) 13313 ); 13314 oCol._setter = null; 13315 13316 oCol.fnGetData = function (rowData, type, meta) { 13317 var innerData = mData( rowData, type, undefined, meta ); 13318 13319 return mRender && type ? 13320 mRender( innerData, type, rowData, meta ) : 13321 innerData; 13322 }; 13323 oCol.fnSetData = function ( rowData, val, meta ) { 13324 return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); 13325 }; 13326 13327 // Indicate if DataTables should read DOM data as an object or array 13328 // Used in _fnGetRowElements 13329 if ( typeof mDataSrc !== 'number' ) { 13330 oSettings._rowReadObject = true; 13331 } 13332 13333 /* Feature sorting overrides column specific when off */ 13334 if ( !oSettings.oFeatures.bSort ) 13335 { 13336 oCol.bSortable = false; 13337 th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called 13338 } 13339 13340 /* Check that the class assignment is correct for sorting */ 13341 var bAsc = $.inArray('asc', oCol.asSorting) !== -1; 13342 var bDesc = $.inArray('desc', oCol.asSorting) !== -1; 13343 if ( !oCol.bSortable || (!bAsc && !bDesc) ) 13344 { 13345 oCol.sSortingClass = oClasses.sSortableNone; 13346 oCol.sSortingClassJUI = ""; 13347 } 13348 else if ( bAsc && !bDesc ) 13349 { 13350 oCol.sSortingClass = oClasses.sSortableAsc; 13351 oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; 13352 } 13353 else if ( !bAsc && bDesc ) 13354 { 13355 oCol.sSortingClass = oClasses.sSortableDesc; 13356 oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; 13357 } 13358 else 13359 { 13360 oCol.sSortingClass = oClasses.sSortable; 13361 oCol.sSortingClassJUI = oClasses.sSortJUI; 13362 } 13363 } 13364 13365 13366 /** 13367 * Adjust the table column widths for new data. Note: you would probably want to 13368 * do a redraw after calling this function! 13369 * @param {object} settings dataTables settings object 13370 * @memberof DataTable#oApi 13371 */ 13372 function _fnAdjustColumnSizing ( settings ) 13373 { 13374 /* Not interested in doing column width calculation if auto-width is disabled */ 13375 if ( settings.oFeatures.bAutoWidth !== false ) 13376 { 13377 var columns = settings.aoColumns; 13378 13379 _fnCalculateColumnWidths( settings ); 13380 for ( var i=0 , iLen=columns.length ; i<iLen ; i++ ) 13381 { 13382 columns[i].nTh.style.width = columns[i].sWidth; 13383 } 13384 } 13385 13386 var scroll = settings.oScroll; 13387 if ( scroll.sY !== '' || scroll.sX !== '') 13388 { 13389 _fnScrollDraw( settings ); 13390 } 13391 13392 _fnCallbackFire( settings, null, 'column-sizing', [settings] ); 13393 } 13394 13395 13396 /** 13397 * Convert the index of a visible column to the index in the data array (take account 13398 * of hidden columns) 13399 * @param {object} oSettings dataTables settings object 13400 * @param {int} iMatch Visible column index to lookup 13401 * @returns {int} i the data index 13402 * @memberof DataTable#oApi 13403 */ 13404 function _fnVisibleToColumnIndex( oSettings, iMatch ) 13405 { 13406 var aiVis = _fnGetColumns( oSettings, 'bVisible' ); 13407 13408 return typeof aiVis[iMatch] === 'number' ? 13409 aiVis[iMatch] : 13410 null; 13411 } 13412 13413 13414 /** 13415 * Convert the index of an index in the data array and convert it to the visible 13416 * column index (take account of hidden columns) 13417 * @param {int} iMatch Column index to lookup 13418 * @param {object} oSettings dataTables settings object 13419 * @returns {int} i the data index 13420 * @memberof DataTable#oApi 13421 */ 13422 function _fnColumnIndexToVisible( oSettings, iMatch ) 13423 { 13424 var aiVis = _fnGetColumns( oSettings, 'bVisible' ); 13425 var iPos = $.inArray( iMatch, aiVis ); 13426 13427 return iPos !== -1 ? iPos : null; 13428 } 13429 13430 13431 /** 13432 * Get the number of visible columns 13433 * @param {object} oSettings dataTables settings object 13434 * @returns {int} i the number of visible columns 13435 * @memberof DataTable#oApi 13436 */ 13437 function _fnVisbleColumns( oSettings ) 13438 { 13439 var vis = 0; 13440 13441 // No reduce in IE8, use a loop for now 13442 $.each( oSettings.aoColumns, function ( i, col ) { 13443 if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) { 13444 vis++; 13445 } 13446 } ); 13447 13448 return vis; 13449 } 13450 13451 13452 /** 13453 * Get an array of column indexes that match a given property 13454 * @param {object} oSettings dataTables settings object 13455 * @param {string} sParam Parameter in aoColumns to look for - typically 13456 * bVisible or bSearchable 13457 * @returns {array} Array of indexes with matched properties 13458 * @memberof DataTable#oApi 13459 */ 13460 function _fnGetColumns( oSettings, sParam ) 13461 { 13462 var a = []; 13463 13464 $.map( oSettings.aoColumns, function(val, i) { 13465 if ( val[sParam] ) { 13466 a.push( i ); 13467 } 13468 } ); 13469 13470 return a; 13471 } 13472 13473 13474 /** 13475 * Calculate the 'type' of a column 13476 * @param {object} settings dataTables settings object 13477 * @memberof DataTable#oApi 13478 */ 13479 function _fnColumnTypes ( settings ) 13480 { 13481 var columns = settings.aoColumns; 13482 var data = settings.aoData; 13483 var types = DataTable.ext.type.detect; 13484 var i, ien, j, jen, k, ken; 13485 var col, cell, detectedType, cache; 13486 13487 // For each column, spin over the 13488 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 13489 col = columns[i]; 13490 cache = []; 13491 13492 if ( ! col.sType && col._sManualType ) { 13493 col.sType = col._sManualType; 13494 } 13495 else if ( ! col.sType ) { 13496 for ( j=0, jen=types.length ; j<jen ; j++ ) { 13497 for ( k=0, ken=data.length ; k<ken ; k++ ) { 13498 // Use a cache array so we only need to get the type data 13499 // from the formatter once (when using multiple detectors) 13500 if ( cache[k] === undefined ) { 13501 cache[k] = _fnGetCellData( settings, k, i, 'type' ); 13502 } 13503 13504 detectedType = types[j]( cache[k], settings ); 13505 13506 // If null, then this type can't apply to this column, so 13507 // rather than testing all cells, break out. There is an 13508 // exception for the last type which is `html`. We need to 13509 // scan all rows since it is possible to mix string and HTML 13510 // types 13511 if ( ! detectedType && j !== types.length-1 ) { 13512 break; 13513 } 13514 13515 // Only a single match is needed for html type since it is 13516 // bottom of the pile and very similar to string - but it 13517 // must not be empty 13518 if ( detectedType === 'html' && ! _empty(cache[k]) ) { 13519 break; 13520 } 13521 } 13522 13523 // Type is valid for all data points in the column - use this 13524 // type 13525 if ( detectedType ) { 13526 col.sType = detectedType; 13527 break; 13528 } 13529 } 13530 13531 // Fall back - if no type was detected, always use string 13532 if ( ! col.sType ) { 13533 col.sType = 'string'; 13534 } 13535 } 13536 } 13537 } 13538 13539 13540 /** 13541 * Take the column definitions and static columns arrays and calculate how 13542 * they relate to column indexes. The callback function will then apply the 13543 * definition found for a column to a suitable configuration object. 13544 * @param {object} oSettings dataTables settings object 13545 * @param {array} aoColDefs The aoColumnDefs array that is to be applied 13546 * @param {array} aoCols The aoColumns array that defines columns individually 13547 * @param {function} fn Callback function - takes two parameters, the calculated 13548 * column index and the definition for that column. 13549 * @memberof DataTable#oApi 13550 */ 13551 function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn ) 13552 { 13553 var i, iLen, j, jLen, k, kLen, def; 13554 var columns = oSettings.aoColumns; 13555 13556 // Column definitions with aTargets 13557 if ( aoColDefs ) 13558 { 13559 /* Loop over the definitions array - loop in reverse so first instance has priority */ 13560 for ( i=aoColDefs.length-1 ; i>=0 ; i-- ) 13561 { 13562 def = aoColDefs[i]; 13563 13564 /* Each definition can target multiple columns, as it is an array */ 13565 var aTargets = def.targets !== undefined ? 13566 def.targets : 13567
vendor: 15,848 bytes, lines 13567-14137
13567def.aTargets; 13568 13569 if ( ! Array.isArray( aTargets ) ) 13570 { 13571 aTargets = [ aTargets ]; 13572 } 13573 13574 for ( j=0, jLen=aTargets.length ; j<jLen ; j++ ) 13575 { 13576 if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 ) 13577 { 13578 /* Add columns that we don't yet know about */ 13579 while( columns.length <= aTargets[j] ) 13580 { 13581 _fnAddColumn( oSettings ); 13582 } 13583 13584 /* Integer, basic index */ 13585 fn( aTargets[j], def ); 13586 } 13587 else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 ) 13588 { 13589 /* Negative integer, right to left column counting */ 13590 fn( columns.length+aTargets[j], def ); 13591 } 13592 else if ( typeof aTargets[j] === 'string' ) 13593 { 13594 /* Class name matching on TH element */ 13595 for ( k=0, kLen=columns.length ; k<kLen ; k++ ) 13596 { 13597 if ( aTargets[j] == "_all" || 13598 $(columns[k].nTh).hasClass( aTargets[j] ) ) 13599 { 13600 fn( k, def ); 13601 } 13602 } 13603 } 13604 } 13605 } 13606 } 13607 13608 // Statically defined columns array 13609 if ( aoCols ) 13610 { 13611 for ( i=0, iLen=aoCols.length ; i<iLen ; i++ ) 13612 { 13613 fn( i, aoCols[i] ); 13614 } 13615 } 13616 } 13617 13618 /** 13619 * Add a data array to the table, creating DOM node etc. This is the parallel to 13620 * _fnGatherData, but for adding rows from a Javascript source, rather than a 13621 * DOM source. 13622 * @param {object} oSettings dataTables settings object 13623 * @param {array} aData data array to be added 13624 * @param {node} [nTr] TR element to add to the table - optional. If not given, 13625 * DataTables will create a row automatically 13626 * @param {array} [anTds] Array of TD|TH elements for the row - must be given 13627 * if nTr is. 13628 * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed 13629 * @memberof DataTable#oApi 13630 */ 13631 function _fnAddData ( oSettings, aDataIn, nTr, anTds ) 13632 { 13633 /* Create the object for storing information about this new row */ 13634 var iRow = oSettings.aoData.length; 13635 var oData = $.extend( true, {}, DataTable.models.oRow, { 13636 src: nTr ? 'dom' : 'data', 13637 idx: iRow 13638 } ); 13639 13640 oData._aData = aDataIn; 13641 oSettings.aoData.push( oData ); 13642 13643 /* Create the cells */ 13644 var nTd, sThisType; 13645 var columns = oSettings.aoColumns; 13646 13647 // Invalidate the column types as the new data needs to be revalidated 13648 for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) 13649 { 13650 columns[i].sType = null; 13651 } 13652 13653 /* Add to the display array */ 13654 oSettings.aiDisplayMaster.push( iRow ); 13655 13656 var id = oSettings.rowIdFn( aDataIn ); 13657 if ( id !== undefined ) { 13658 oSettings.aIds[ id ] = oData; 13659 } 13660 13661 /* Create the DOM information, or register it if already present */ 13662 if ( nTr || ! oSettings.oFeatures.bDeferRender ) 13663 { 13664 _fnCreateTr( oSettings, iRow, nTr, anTds ); 13665 } 13666 13667 return iRow; 13668 } 13669 13670 13671 /** 13672 * Add one or more TR elements to the table. Generally we'd expect to 13673 * use this for reading data from a DOM sourced table, but it could be 13674 * used for an TR element. Note that if a TR is given, it is used (i.e. 13675 * it is not cloned). 13676 * @param {object} settings dataTables settings object 13677 * @param {array|node|jQuery} trs The TR element(s) to add to the table 13678 * @returns {array} Array of indexes for the added rows 13679 * @memberof DataTable#oApi 13680 */ 13681 function _fnAddTr( settings, trs ) 13682 { 13683 var row; 13684 13685 // Allow an individual node to be passed in 13686 if ( ! (trs instanceof $) ) { 13687 trs = $(trs); 13688 } 13689 13690 return trs.map( function (i, el) { 13691 row = _fnGetRowElements( settings, el ); 13692 return _fnAddData( settings, row.data, el, row.cells ); 13693 } ); 13694 } 13695 13696 13697 /** 13698 * Take a TR element and convert it to an index in aoData 13699 * @param {object} oSettings dataTables settings object 13700 * @param {node} n the TR element to find 13701 * @returns {int} index if the node is found, null if not 13702 * @memberof DataTable#oApi 13703 */ 13704 function _fnNodeToDataIndex( oSettings, n ) 13705 { 13706 return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null; 13707 } 13708 13709 13710 /** 13711 * Take a TD element and convert it into a column data index (not the visible index) 13712 * @param {object} oSettings dataTables settings object 13713 * @param {int} iRow The row number the TD/TH can be found in 13714 * @param {node} n The TD/TH element to find 13715 * @returns {int} index if the node is found, -1 if not 13716 * @memberof DataTable#oApi 13717 */ 13718 function _fnNodeToColumnIndex( oSettings, iRow, n ) 13719 { 13720 return $.inArray( n, oSettings.aoData[ iRow ].anCells ); 13721 } 13722 13723 13724 /** 13725 * Get the data for a given cell from the internal cache, taking into account data mapping 13726 * @param {object} settings dataTables settings object 13727 * @param {int} rowIdx aoData row id 13728 * @param {int} colIdx Column index 13729 * @param {string} type data get type ('display', 'type' 'filter|search' 'sort|order') 13730 * @returns {*} Cell data 13731 * @memberof DataTable#oApi 13732 */ 13733 function _fnGetCellData( settings, rowIdx, colIdx, type ) 13734 { 13735 if (type === 'search') { 13736 type = 'filter'; 13737 } 13738 else if (type === 'order') { 13739 type = 'sort'; 13740 } 13741 13742 var draw = settings.iDraw; 13743 var col = settings.aoColumns[colIdx]; 13744 var rowData = settings.aoData[rowIdx]._aData; 13745 var defaultContent = col.sDefaultContent; 13746 var cellData = col.fnGetData( rowData, type, { 13747 settings: settings, 13748 row: rowIdx, 13749 col: colIdx 13750 } ); 13751 13752 if ( cellData === undefined ) { 13753 if ( settings.iDrawError != draw && defaultContent === null ) { 13754 _fnLog( settings, 0, "Requested unknown parameter "+ 13755 (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+ 13756 " for row "+rowIdx+", column "+colIdx, 4 ); 13757 settings.iDrawError = draw; 13758 } 13759 return defaultContent; 13760 } 13761 13762 // When the data source is null and a specific data type is requested (i.e. 13763 // not the original data), we can use default column data 13764 if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) { 13765 cellData = defaultContent; 13766 } 13767 else if ( typeof cellData === 'function' ) { 13768 // If the data source is a function, then we run it and use the return, 13769 // executing in the scope of the data object (for instances) 13770 return cellData.call( rowData ); 13771 } 13772 13773 if ( cellData === null && type === 'display' ) { 13774 return ''; 13775 } 13776 13777 if ( type === 'filter' ) { 13778 var fomatters = DataTable.ext.type.search; 13779 13780 if ( fomatters[ col.sType ] ) { 13781 cellData = fomatters[ col.sType ]( cellData ); 13782 } 13783 } 13784 13785 return cellData; 13786 } 13787 13788 13789 /** 13790 * Set the value for a specific cell, into the internal data cache 13791 * @param {object} settings dataTables settings object 13792 * @param {int} rowIdx aoData row id 13793 * @param {int} colIdx Column index 13794 * @param {*} val Value to set 13795 * @memberof DataTable#oApi 13796 */ 13797 function _fnSetCellData( settings, rowIdx, colIdx, val ) 13798 { 13799 var col = settings.aoColumns[colIdx]; 13800 var rowData = settings.aoData[rowIdx]._aData; 13801 13802 col.fnSetData( rowData, val, { 13803 settings: settings, 13804 row: rowIdx, 13805 col: colIdx 13806 } ); 13807 } 13808 13809 13810 // Private variable that is used to match action syntax in the data property object 13811 var __reArray = /\[.*?\]$/; 13812 var __reFn = /\(\)$/; 13813 13814 /** 13815 * Split string on periods, taking into account escaped periods 13816 * @param {string} str String to split 13817 * @return {array} Split string 13818 */ 13819 function _fnSplitObjNotation( str ) 13820 { 13821 return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) { 13822 return s.replace(/\\\./g, '.'); 13823 } ); 13824 } 13825 13826 13827 /** 13828 * Return a function that can be used to get data from a source object, taking 13829 * into account the ability to use nested objects as a source 13830 * @param {string|int|function} mSource The data source for the object 13831 * @returns {function} Data get function 13832 * @memberof DataTable#oApi 13833 */ 13834 var _fnGetObjectDataFn = DataTable.util.get; 13835 13836 13837 /** 13838 * Return a function that can be used to set data from a source object, taking 13839 * into account the ability to use nested objects as a source 13840 * @param {string|int|function} mSource The data source for the object 13841 * @returns {function} Data set function 13842 * @memberof DataTable#oApi 13843 */ 13844 var _fnSetObjectDataFn = DataTable.util.set; 13845 13846 13847 /** 13848 * Return an array with the full table data 13849 * @param {object} oSettings dataTables settings object 13850 * @returns array {array} aData Master data array 13851 * @memberof DataTable#oApi 13852 */ 13853 function _fnGetDataMaster ( settings ) 13854 { 13855 return _pluck( settings.aoData, '_aData' ); 13856 } 13857 13858 13859 /** 13860 * Nuke the table 13861 * @param {object} oSettings dataTables settings object 13862 * @memberof DataTable#oApi 13863 */ 13864 function _fnClearTable( settings ) 13865 { 13866 settings.aoData.length = 0; 13867 settings.aiDisplayMaster.length = 0; 13868 settings.aiDisplay.length = 0; 13869 settings.aIds = {}; 13870 } 13871 13872 13873 /** 13874 * Take an array of integers (index array) and remove a target integer (value - not 13875 * the key!) 13876 * @param {array} a Index array to target 13877 * @param {int} iTarget value to find 13878 * @memberof DataTable#oApi 13879 */ 13880 function _fnDeleteIndex( a, iTarget, splice ) 13881 { 13882 var iTargetIndex = -1; 13883 13884 for ( var i=0, iLen=a.length ; i<iLen ; i++ ) 13885 { 13886 if ( a[i] == iTarget ) 13887 { 13888 iTargetIndex = i; 13889 } 13890 else if ( a[i] > iTarget ) 13891 { 13892 a[i]--; 13893 } 13894 } 13895 13896 if ( iTargetIndex != -1 && splice === undefined ) 13897 { 13898 a.splice( iTargetIndex, 1 ); 13899 } 13900 } 13901 13902 13903 /** 13904 * Mark cached data as invalid such that a re-read of the data will occur when 13905 * the cached data is next requested. Also update from the data source object. 13906 * 13907 * @param {object} settings DataTables settings object 13908 * @param {int} rowIdx Row index to invalidate 13909 * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom' 13910 * or 'data' 13911 * @param {int} [colIdx] Column index to invalidate. If undefined the whole 13912 * row will be invalidated 13913 * @memberof DataTable#oApi 13914 * 13915 * @todo For the modularisation of v1.11 this will need to become a callback, so 13916 * the sort and filter methods can subscribe to it. That will required 13917 * initialisation options for sorting, which is why it is not already baked in 13918 */ 13919 function _fnInvalidate( settings, rowIdx, src, colIdx ) 13920 { 13921 var row = settings.aoData[ rowIdx ]; 13922 var i, ien; 13923 var cellWrite = function ( cell, col ) { 13924 // This is very frustrating, but in IE if you just write directly 13925 // to innerHTML, and elements that are overwritten are GC'ed, 13926 // even if there is a reference to them elsewhere 13927 while ( cell.childNodes.length ) { 13928 cell.removeChild( cell.firstChild ); 13929 } 13930 13931 cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' ); 13932 }; 13933 13934 // Are we reading last data from DOM or the data object? 13935 if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) { 13936 // Read the data from the DOM 13937 row._aData = _fnGetRowElements( 13938 settings, row, colIdx, colIdx === undefined ? undefined : row._aData 13939 ) 13940 .data; 13941 } 13942 else { 13943 // Reading from data object, update the DOM 13944 var cells = row.anCells; 13945 13946 if ( cells ) { 13947 if ( colIdx !== undefined ) { 13948 cellWrite( cells[colIdx], colIdx ); 13949 } 13950 else { 13951 for ( i=0, ien=cells.length ; i<ien ; i++ ) { 13952 cellWrite( cells[i], i ); 13953 } 13954 } 13955 } 13956 } 13957 13958 // For both row and cell invalidation, the cached data for sorting and 13959 // filtering is nulled out 13960 row._aSortData = null; 13961 row._aFilterData = null; 13962 13963 // Invalidate the type for a specific column (if given) or all columns since 13964 // the data might have changed 13965 var cols = settings.aoColumns; 13966 if ( colIdx !== undefined ) { 13967 cols[ colIdx ].sType = null; 13968 } 13969 else { 13970 for ( i=0, ien=cols.length ; i<ien ; i++ ) { 13971 cols[i].sType = null; 13972 } 13973 13974 // Update DataTables special `DT_*` attributes for the row 13975 _fnRowAttributes( settings, row ); 13976 } 13977 } 13978 13979 13980 /** 13981 * Build a data source object from an HTML row, reading the contents of the 13982 * cells that are in the row. 13983 * 13984 * @param {object} settings DataTables settings object 13985 * @param {node|object} TR element from which to read data or existing row 13986 * object from which to re-read the data from the cells 13987 * @param {int} [colIdx] Optional column index 13988 * @param {array|object} [d] Data source object. If `colIdx` is given then this 13989 * parameter should also be given and will be used to write the data into. 13990 * Only the column in question will be written 13991 * @returns {object} Object with two parameters: `data` the data read, in 13992 * document order, and `cells` and array of nodes (they can be useful to the 13993 * caller, so rather than needing a second traversal to get them, just return 13994 * them from here). 13995 * @memberof DataTable#oApi 13996 */ 13997 function _fnGetRowElements( settings, row, colIdx, d ) 13998 { 13999 var 14000 tds = [], 14001 td = row.firstChild, 14002 name, col, o, i=0, contents, 14003 columns = settings.aoColumns, 14004 objectRead = settings._rowReadObject; 14005 14006 // Allow the data object to be passed in, or construct 14007 d = d !== undefined ? 14008 d : 14009 objectRead ? 14010 {} : 14011 []; 14012 14013 var attr = function ( str, td ) { 14014 if ( typeof str === 'string' ) { 14015 var idx = str.indexOf('@'); 14016 14017 if ( idx !== -1 ) { 14018 var attr = str.substring( idx+1 ); 14019 var setter = _fnSetObjectDataFn( str ); 14020 setter( d, td.getAttribute( attr ) ); 14021 } 14022 } 14023 }; 14024 14025 // Read data from a cell and store into the data object 14026 var cellProcess = function ( cell ) { 14027 if ( colIdx === undefined || colIdx === i ) { 14028 col = columns[i]; 14029 contents = (cell.innerHTML).trim(); 14030 14031 if ( col && col._bAttrSrc ) { 14032 var setter = _fnSetObjectDataFn( col.mData._ ); 14033 setter( d, contents ); 14034 14035 attr( col.mData.sort, cell ); 14036 attr( col.mData.type, cell ); 14037 attr( col.mData.filter, cell ); 14038 } 14039 else { 14040 // Depending on the `data` option for the columns the data can 14041 // be read to either an object or an array. 14042 if ( objectRead ) { 14043 if ( ! col._setter ) { 14044 // Cache the setter function 14045 col._setter = _fnSetObjectDataFn( col.mData ); 14046 } 14047 col._setter( d, contents ); 14048 } 14049 else { 14050 d[i] = contents; 14051 } 14052 } 14053 } 14054 14055 i++; 14056 }; 14057 14058 if ( td ) { 14059 // `tr` element was passed in 14060 while ( td ) { 14061 name = td.nodeName.toUpperCase(); 14062 14063 if ( name == "TD" || name == "TH" ) { 14064 cellProcess( td ); 14065 tds.push( td ); 14066 } 14067 14068 td = td.nextSibling; 14069 } 14070 } 14071 else { 14072 // Existing row object passed in 14073 tds = row.anCells; 14074 14075 for ( var j=0, jen=tds.length ; j<jen ; j++ ) { 14076 cellProcess( tds[j] ); 14077 } 14078 } 14079 14080 // Read the ID from the DOM if present 14081 var rowNode = row.firstChild ? row : row.nTr; 14082 14083 if ( rowNode ) { 14084 var id = rowNode.getAttribute( 'id' ); 14085 14086 if ( id ) { 14087 _fnSetObjectDataFn( settings.rowId )( d, id ); 14088 } 14089 } 14090 14091 return { 14092 data: d, 14093 cells: tds 14094 }; 14095 } 14096 /** 14097 * Create a new TR element (and it's TD children) for a row 14098 * @param {object} oSettings dataTables settings object 14099 * @param {int} iRow Row to consider 14100 * @param {node} [nTrIn] TR element to add to the table - optional. If not given, 14101 * DataTables will create a row automatically 14102 * @param {array} [anTds] Array of TD|TH elements for the row - must be given 14103 * if nTr is. 14104 * @memberof DataTable#oApi 14105 */ 14106 function _fnCreateTr ( oSettings, iRow, nTrIn, anTds ) 14107 { 14108 var 14109 row = oSettings.aoData[iRow], 14110 rowData = row._aData, 14111 cells = [], 14112 nTr, nTd, oCol, 14113 i, iLen, create; 14114 14115 if ( row.nTr === null ) 14116 { 14117 nTr = nTrIn || document.createElement('tr'); 14118 14119 row.nTr = nTr; 14120 row.anCells = cells; 14121 14122 /* Use a private property on the node to allow reserve mapping from the node 14123 * to the aoData array for fast look up 14124 */ 14125 nTr._DT_RowIndex = iRow; 14126 14127 /* Special parameters can be given by the data source to be used on the row */ 14128 _fnRowAttributes( oSettings, row ); 14129 14130 /* Process each column */ 14131 for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) 14132 { 14133 oCol = oSettings.aoColumns[i]; 14134 create = nTrIn ? false : true; 14135 14136 nTd = create ? document.createElement( oCol.sCellType ) : anTds[i]; 14137
vendor: 8,418 bytes, lines 14137-14445
14137 nTd._DT_CellIndex = { 14138 row: iRow, 14139 column: i 14140 }; 14141 14142 cells.push( nTd ); 14143 14144 // Need to create the HTML if new, or if a rendering function is defined 14145 if ( create || ((oCol.mRender || oCol.mData !== i) && 14146 (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display') 14147 )) { 14148 nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' ); 14149 } 14150 14151 /* Add user defined class */ 14152 if ( oCol.sClass ) 14153 { 14154 nTd.className += ' '+oCol.sClass; 14155 } 14156 14157 // Visibility - add or remove as required 14158 if ( oCol.bVisible && ! nTrIn ) 14159 { 14160 nTr.appendChild( nTd ); 14161 } 14162 else if ( ! oCol.bVisible && nTrIn ) 14163 { 14164 nTd.parentNode.removeChild( nTd ); 14165 } 14166 14167 if ( oCol.fnCreatedCell ) 14168 { 14169 oCol.fnCreatedCell.call( oSettings.oInstance, 14170 nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i 14171 ); 14172 } 14173 } 14174 14175 _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow, cells] ); 14176 } 14177 } 14178 14179 14180 /** 14181 * Add attributes to a row based on the special `DT_*` parameters in a data 14182 * source object. 14183 * @param {object} settings DataTables settings object 14184 * @param {object} DataTables row object for the row to be modified 14185 * @memberof DataTable#oApi 14186 */ 14187 function _fnRowAttributes( settings, row ) 14188 { 14189 var tr = row.nTr; 14190 var data = row._aData; 14191 14192 if ( tr ) { 14193 var id = settings.rowIdFn( data ); 14194 14195 if ( id ) { 14196 tr.id = id; 14197 } 14198 14199 if ( data.DT_RowClass ) { 14200 // Remove any classes added by DT_RowClass before 14201 var a = data.DT_RowClass.split(' '); 14202 row.__rowc = row.__rowc ? 14203 _unique( row.__rowc.concat( a ) ) : 14204 a; 14205 14206 $(tr) 14207 .removeClass( row.__rowc.join(' ') ) 14208 .addClass( data.DT_RowClass ); 14209 } 14210 14211 if ( data.DT_RowAttr ) { 14212 $(tr).attr( data.DT_RowAttr ); 14213 } 14214 14215 if ( data.DT_RowData ) { 14216 $(tr).data( data.DT_RowData ); 14217 } 14218 } 14219 } 14220 14221 14222 /** 14223 * Create the HTML header for the table 14224 * @param {object} oSettings dataTables settings object 14225 * @memberof DataTable#oApi 14226 */ 14227 function _fnBuildHead( oSettings ) 14228 { 14229 var i, ien, cell, row, column; 14230 var thead = oSettings.nTHead; 14231 var tfoot = oSettings.nTFoot; 14232 var createHeader = $('th, td', thead).length === 0; 14233 var classes = oSettings.oClasses; 14234 var columns = oSettings.aoColumns; 14235 14236 if ( createHeader ) { 14237 row = $('<tr/>').appendTo( thead ); 14238 } 14239 14240 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 14241 column = columns[i]; 14242 cell = $( column.nTh ).addClass( column.sClass ); 14243 14244 if ( createHeader ) { 14245 cell.appendTo( row ); 14246 } 14247 14248 // 1.11 move into sorting 14249 if ( oSettings.oFeatures.bSort ) { 14250 cell.addClass( column.sSortingClass ); 14251 14252 if ( column.bSortable !== false ) { 14253 cell 14254 .attr( 'tabindex', oSettings.iTabIndex ) 14255 .attr( 'aria-controls', oSettings.sTableId ); 14256 14257 _fnSortAttachListener( oSettings, column.nTh, i ); 14258 } 14259 } 14260 14261 if ( column.sTitle != cell[0].innerHTML ) { 14262 cell.html( column.sTitle ); 14263 } 14264 14265 _fnRenderer( oSettings, 'header' )( 14266 oSettings, cell, column, classes 14267 ); 14268 } 14269 14270 if ( createHeader ) { 14271 _fnDetectHeader( oSettings.aoHeader, thead ); 14272 } 14273 14274 /* Deal with the footer - add classes if required */ 14275 $(thead).children('tr').children('th, td').addClass( classes.sHeaderTH ); 14276 $(tfoot).children('tr').children('th, td').addClass( classes.sFooterTH ); 14277 14278 // Cache the footer cells. Note that we only take the cells from the first 14279 // row in the footer. If there is more than one row the user wants to 14280 // interact with, they need to use the table().foot() method. Note also this 14281 // allows cells to be used for multiple columns using colspan 14282 if ( tfoot !== null ) { 14283 var cells = oSettings.aoFooter[0]; 14284 14285 for ( i=0, ien=cells.length ; i<ien ; i++ ) { 14286 column = columns[i]; 14287 column.nTf = cells[i].cell; 14288 14289 if ( column.sClass ) { 14290 $(column.nTf).addClass( column.sClass ); 14291 } 14292 } 14293 } 14294 } 14295 14296 14297 /** 14298 * Draw the header (or footer) element based on the column visibility states. The 14299 * methodology here is to use the layout array from _fnDetectHeader, modified for 14300 * the instantaneous column visibility, to construct the new layout. The grid is 14301 * traversed over cell at a time in a rows x columns grid fashion, although each 14302 * cell insert can cover multiple elements in the grid - which is tracks using the 14303 * aApplied array. Cell inserts in the grid will only occur where there isn't 14304 * already a cell in that position. 14305 * @param {object} oSettings dataTables settings object 14306 * @param array {objects} aoSource Layout array from _fnDetectHeader 14307 * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc, 14308 * @memberof DataTable#oApi 14309 */ 14310 function _fnDrawHead( oSettings, aoSource, bIncludeHidden ) 14311 { 14312 var i, iLen, j, jLen, k, kLen, n, nLocalTr; 14313 var aoLocal = []; 14314 var aApplied = []; 14315 var iColumns = oSettings.aoColumns.length; 14316 var iRowspan, iColspan; 14317 14318 if ( ! aoSource ) 14319 { 14320 return; 14321 } 14322 14323 if ( bIncludeHidden === undefined ) 14324 { 14325 bIncludeHidden = false; 14326 } 14327 14328 /* Make a copy of the master layout array, but without the visible columns in it */ 14329 for ( i=0, iLen=aoSource.length ; i<iLen ; i++ ) 14330 { 14331 aoLocal[i] = aoSource[i].slice(); 14332 aoLocal[i].nTr = aoSource[i].nTr; 14333 14334 /* Remove any columns which are currently hidden */ 14335 for ( j=iColumns-1 ; j>=0 ; j-- ) 14336 { 14337 if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden ) 14338 { 14339 aoLocal[i].splice( j, 1 ); 14340 } 14341 } 14342 14343 /* Prep the applied array - it needs an element for each row */ 14344 aApplied.push( [] ); 14345 } 14346 14347 for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ ) 14348 { 14349 nLocalTr = aoLocal[i].nTr; 14350 14351 /* All cells are going to be replaced, so empty out the row */ 14352 if ( nLocalTr ) 14353 { 14354 while( (n = nLocalTr.firstChild) ) 14355 { 14356 nLocalTr.removeChild( n ); 14357 } 14358 } 14359 14360 for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ ) 14361 { 14362 iRowspan = 1; 14363 iColspan = 1; 14364 14365 /* Check to see if there is already a cell (row/colspan) covering our target 14366 * insert point. If there is, then there is nothing to do. 14367 */ 14368 if ( aApplied[i][j] === undefined ) 14369 { 14370 nLocalTr.appendChild( aoLocal[i][j].cell ); 14371 aApplied[i][j] = 1; 14372 14373 /* Expand the cell to cover as many rows as needed */ 14374 while ( aoLocal[i+iRowspan] !== undefined && 14375 aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell ) 14376 { 14377 aApplied[i+iRowspan][j] = 1; 14378 iRowspan++; 14379 } 14380 14381 /* Expand the cell to cover as many columns as needed */ 14382 while ( aoLocal[i][j+iColspan] !== undefined && 14383 aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell ) 14384 { 14385 /* Must update the applied array over the rows for the columns */ 14386 for ( k=0 ; k<iRowspan ; k++ ) 14387 { 14388 aApplied[i+k][j+iColspan] = 1; 14389 } 14390 iColspan++; 14391 } 14392 14393 /* Do the actual expansion in the DOM */ 14394 $(aoLocal[i][j].cell) 14395 .attr('rowspan', iRowspan) 14396 .attr('colspan', iColspan); 14397 } 14398 } 14399 } 14400 } 14401 14402 14403 /** 14404 * Insert the required TR nodes into the table for display 14405 * @param {object} oSettings dataTables settings object 14406 * @param ajaxComplete true after ajax call to complete rendering 14407 * @memberof DataTable#oApi 14408 */ 14409 function _fnDraw( oSettings, ajaxComplete ) 14410 { 14411 /* Provide a pre-callback function which can be used to cancel the draw is false is returned */ 14412 var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] ); 14413 if ( $.inArray( false, aPreDraw ) !== -1 ) 14414 { 14415 _fnProcessingDisplay( oSettings, false ); 14416 return; 14417 } 14418 14419 var i, iLen, n; 14420 var anRows = []; 14421 var iRowCount = 0; 14422 var asStripeClasses = oSettings.asStripeClasses; 14423 var iStripes = asStripeClasses.length; 14424 var iOpenRows = oSettings.aoOpenRows.length; 14425 var oLang = oSettings.oLanguage; 14426 var iInitDisplayStart = oSettings.iInitDisplayStart; 14427 var bServerSide = _fnDataSource( oSettings ) == 'ssp'; 14428 var aiDisplay = oSettings.aiDisplay; 14429 14430 oSettings.bDrawing = true; 14431 14432 /* Check and see if we have an initial draw position from state saving */ 14433 if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 ) 14434 { 14435 oSettings._iDisplayStart = bServerSide ? 14436 iInitDisplayStart : 14437 iInitDisplayStart >= oSettings.fnRecordsDisplay() ? 14438 0 : 14439 iInitDisplayStart; 14440 14441 oSettings.iInitDisplayStart = -1; 14442 } 14443 14444 var iDisplayStart = oSettings._iDisplayStart; 14445 var iDisplayEnd = oSettings.fnDisplayEnd()
vendor: 10,841 bytes, lines 14445-14849
14445; 14446 14447 /* Server-side processing draw intercept */ 14448 if ( oSettings.bDeferLoading ) 14449 { 14450 oSettings.bDeferLoading = false; 14451 oSettings.iDraw++; 14452 _fnProcessingDisplay( oSettings, false ); 14453 } 14454 else if ( !bServerSide ) 14455 { 14456 oSettings.iDraw++; 14457 } 14458 else if ( !oSettings.bDestroying && !ajaxComplete) 14459 { 14460 _fnAjaxUpdate( oSettings ); 14461 return; 14462 } 14463 14464 if ( aiDisplay.length !== 0 ) 14465 { 14466 var iStart = bServerSide ? 0 : iDisplayStart; 14467 var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd; 14468 14469 for ( var j=iStart ; j<iEnd ; j++ ) 14470 { 14471 var iDataIndex = aiDisplay[j]; 14472 var aoData = oSettings.aoData[ iDataIndex ]; 14473 if ( aoData.nTr === null ) 14474 { 14475 _fnCreateTr( oSettings, iDataIndex ); 14476 } 14477 14478 var nRow = aoData.nTr; 14479 14480 /* Remove the old striping classes and then add the new one */ 14481 if ( iStripes !== 0 ) 14482 { 14483 var sStripe = asStripeClasses[ iRowCount % iStripes ]; 14484 if ( aoData._sRowStripe != sStripe ) 14485 { 14486 $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe ); 14487 aoData._sRowStripe = sStripe; 14488 } 14489 } 14490 14491 // Row callback functions - might want to manipulate the row 14492 // iRowCount and j are not currently documented. Are they at all 14493 // useful? 14494 _fnCallbackFire( oSettings, 'aoRowCallback', null, 14495 [nRow, aoData._aData, iRowCount, j, iDataIndex] ); 14496 14497 anRows.push( nRow ); 14498 iRowCount++; 14499 } 14500 } 14501 else 14502 { 14503 /* Table is empty - create a row with an empty message in it */ 14504 var sZero = oLang.sZeroRecords; 14505 if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' ) 14506 { 14507 sZero = oLang.sLoadingRecords; 14508 } 14509 else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 ) 14510 { 14511 sZero = oLang.sEmptyTable; 14512 } 14513 14514 anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } ) 14515 .append( $('<td />', { 14516 'valign': 'top', 14517 'colSpan': _fnVisbleColumns( oSettings ), 14518 'class': oSettings.oClasses.sRowEmpty 14519 } ).html( sZero ) )[0]; 14520 } 14521 14522 /* Header and footer callbacks */ 14523 _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0], 14524 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); 14525 14526 _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0], 14527 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] ); 14528 14529 var body = $(oSettings.nTBody); 14530 14531 body.children().detach(); 14532 body.append( $(anRows) ); 14533 14534 /* Call all required callback functions for the end of a draw */ 14535 _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] ); 14536 14537 /* Draw is complete, sorting and filtering must be as well */ 14538 oSettings.bSorted = false; 14539 oSettings.bFiltered = false; 14540 oSettings.bDrawing = false; 14541 } 14542 14543 14544 /** 14545 * Redraw the table - taking account of the various features which are enabled 14546 * @param {object} oSettings dataTables settings object 14547 * @param {boolean} [holdPosition] Keep the current paging position. By default 14548 * the paging is reset to the first page 14549 * @memberof DataTable#oApi 14550 */ 14551 function _fnReDraw( settings, holdPosition ) 14552 { 14553 var 14554 features = settings.oFeatures, 14555 sort = features.bSort, 14556 filter = features.bFilter; 14557 14558 if ( sort ) { 14559 _fnSort( settings ); 14560 } 14561 14562 if ( filter ) { 14563 _fnFilterComplete( settings, settings.oPreviousSearch ); 14564 } 14565 else { 14566 // No filtering, so we want to just use the display master 14567 settings.aiDisplay = settings.aiDisplayMaster.slice(); 14568 } 14569 14570 if ( holdPosition !== true ) { 14571 settings._iDisplayStart = 0; 14572 } 14573 14574 // Let any modules know about the draw hold position state (used by 14575 // scrolling internally) 14576 settings._drawHold = holdPosition; 14577 14578 _fnDraw( settings ); 14579 14580 settings._drawHold = false; 14581 } 14582 14583 14584 /** 14585 * Add the options to the page HTML for the table 14586 * @param {object} oSettings dataTables settings object 14587 * @memberof DataTable#oApi 14588 */ 14589 function _fnAddOptionsHtml ( oSettings ) 14590 { 14591 var classes = oSettings.oClasses; 14592 var table = $(oSettings.nTable); 14593 var holding = $('<div/>').insertBefore( table ); // Holding element for speed 14594 var features = oSettings.oFeatures; 14595 14596 // All DataTables are wrapped in a div 14597 var insert = $('<div/>', { 14598 id: oSettings.sTableId+'_wrapper', 14599 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter) 14600 } ); 14601 14602 oSettings.nHolding = holding[0]; 14603 oSettings.nTableWrapper = insert[0]; 14604 oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; 14605 14606 /* Loop over the user set positioning and place the elements as needed */ 14607 var aDom = oSettings.sDom.split(''); 14608 var featureNode, cOption, nNewNode, cNext, sAttr, j; 14609 for ( var i=0 ; i<aDom.length ; i++ ) 14610 { 14611 featureNode = null; 14612 cOption = aDom[i]; 14613 14614 if ( cOption == '<' ) 14615 { 14616 /* New container div */ 14617 nNewNode = $('<div/>')[0]; 14618 14619 /* Check to see if we should append an id and/or a class name to the container */ 14620 cNext = aDom[i+1]; 14621 if ( cNext == "'" || cNext == '"' ) 14622 { 14623 sAttr = ""; 14624 j = 2; 14625 while ( aDom[i+j] != cNext ) 14626 { 14627 sAttr += aDom[i+j]; 14628 j++; 14629 } 14630 14631 /* Replace jQuery UI constants @todo depreciated */ 14632 if ( sAttr == "H" ) 14633 { 14634 sAttr = classes.sJUIHeader; 14635 } 14636 else if ( sAttr == "F" ) 14637 { 14638 sAttr = classes.sJUIFooter; 14639 } 14640 14641 /* The attribute can be in the format of "#id.class", "#id" or "class" This logic 14642 * breaks the string into parts and applies them as needed 14643 */ 14644 if ( sAttr.indexOf('.') != -1 ) 14645 { 14646 var aSplit = sAttr.split('.'); 14647 nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); 14648 nNewNode.className = aSplit[1]; 14649 } 14650 else if ( sAttr.charAt(0) == "#" ) 14651 { 14652 nNewNode.id = sAttr.substr(1, sAttr.length-1); 14653 } 14654 else 14655 { 14656 nNewNode.className = sAttr; 14657 } 14658 14659 i += j; /* Move along the position array */ 14660 } 14661 14662 insert.append( nNewNode ); 14663 insert = $(nNewNode); 14664 } 14665 else if ( cOption == '>' ) 14666 { 14667 /* End container div */ 14668 insert = insert.parent(); 14669 } 14670 // @todo Move options into their own plugins? 14671 else if ( cOption == 'l' && features.bPaginate && features.bLengthChange ) 14672 { 14673 /* Length */ 14674 featureNode = _fnFeatureHtmlLength( oSettings ); 14675 } 14676 else if ( cOption == 'f' && features.bFilter ) 14677 { 14678 /* Filter */ 14679 featureNode = _fnFeatureHtmlFilter( oSettings ); 14680 } 14681 else if ( cOption == 'r' && features.bProcessing ) 14682 { 14683 /* pRocessing */ 14684 featureNode = _fnFeatureHtmlProcessing( oSettings ); 14685 } 14686 else if ( cOption == 't' ) 14687 { 14688 /* Table */ 14689 featureNode = _fnFeatureHtmlTable( oSettings ); 14690 } 14691 else if ( cOption == 'i' && features.bInfo ) 14692 { 14693 /* Info */ 14694 featureNode = _fnFeatureHtmlInfo( oSettings ); 14695 } 14696 else if ( cOption == 'p' && features.bPaginate ) 14697 { 14698 /* Pagination */ 14699 featureNode = _fnFeatureHtmlPaginate( oSettings ); 14700 } 14701 else if ( DataTable.ext.feature.length !== 0 ) 14702 { 14703 /* Plug-in features */ 14704 var aoFeatures = DataTable.ext.feature; 14705 for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ ) 14706 { 14707 if ( cOption == aoFeatures[k].cFeature ) 14708 { 14709 featureNode = aoFeatures[k].fnInit( oSettings ); 14710 break; 14711 } 14712 } 14713 } 14714 14715 /* Add to the 2D features array */ 14716 if ( featureNode ) 14717 { 14718 var aanFeatures = oSettings.aanFeatures; 14719 14720 if ( ! aanFeatures[cOption] ) 14721 { 14722 aanFeatures[cOption] = []; 14723 } 14724 14725 aanFeatures[cOption].push( featureNode ); 14726 insert.append( featureNode ); 14727 } 14728 } 14729 14730 /* Built our DOM structure - replace the holding div with what we want */ 14731 holding.replaceWith( insert ); 14732 oSettings.nHolding = null; 14733 } 14734 14735 14736 /** 14737 * Use the DOM source to create up an array of header cells. The idea here is to 14738 * create a layout grid (array) of rows x columns, which contains a reference 14739 * to the cell that that point in the grid (regardless of col/rowspan), such that 14740 * any column / row could be removed and the new grid constructed 14741 * @param array {object} aLayout Array to store the calculated layout in 14742 * @param {node} nThead The header/footer element for the table 14743 * @memberof DataTable#oApi 14744 */ 14745 function _fnDetectHeader ( aLayout, nThead ) 14746 { 14747 var nTrs = $(nThead).children('tr'); 14748 var nTr, nCell; 14749 var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan; 14750 var bUnique; 14751 var fnShiftCol = function ( a, i, j ) { 14752 var k = a[i]; 14753 while ( k[j] ) { 14754 j++; 14755 } 14756 return j; 14757 }; 14758 14759 aLayout.splice( 0, aLayout.length ); 14760 14761 /* We know how many rows there are in the layout - so prep it */ 14762 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) 14763 { 14764 aLayout.push( [] ); 14765 } 14766 14767 /* Calculate a layout array */ 14768 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) 14769 { 14770 nTr = nTrs[i]; 14771 iColumn = 0; 14772 14773 /* For every cell in the row... */ 14774 nCell = nTr.firstChild; 14775 while ( nCell ) { 14776 if ( nCell.nodeName.toUpperCase() == "TD" || 14777 nCell.nodeName.toUpperCase() == "TH" ) 14778 { 14779 /* Get the col and rowspan attributes from the DOM and sanitise them */ 14780 iColspan = nCell.getAttribute('colspan') * 1; 14781 iRowspan = nCell.getAttribute('rowspan') * 1; 14782 iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan; 14783 iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan; 14784 14785 /* There might be colspan cells already in this row, so shift our target 14786 * accordingly 14787 */ 14788 iColShifted = fnShiftCol( aLayout, i, iColumn ); 14789 14790 /* Cache calculation for unique columns */ 14791 bUnique = iColspan === 1 ? true : false; 14792 14793 /* If there is col / rowspan, copy the information into the layout grid */ 14794 for ( l=0 ; l<iColspan ; l++ ) 14795 { 14796 for ( k=0 ; k<iRowspan ; k++ ) 14797 { 14798 aLayout[i+k][iColShifted+l] = { 14799 "cell": nCell, 14800 "unique": bUnique 14801 }; 14802 aLayout[i+k].nTr = nTr; 14803 } 14804 } 14805 } 14806 nCell = nCell.nextSibling; 14807 } 14808 } 14809 } 14810 14811 14812 /** 14813 * Get an array of unique th elements, one for each column 14814 * @param {object} oSettings dataTables settings object 14815 * @param {node} nHeader automatically detect the layout from this node - optional 14816 * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional 14817 * @returns array {node} aReturn list of unique th's 14818 * @memberof DataTable#oApi 14819 */ 14820 function _fnGetUniqueThs ( oSettings, nHeader, aLayout ) 14821 { 14822 var aReturn = []; 14823 if ( !aLayout ) 14824 { 14825 aLayout = oSettings.aoHeader; 14826 if ( nHeader ) 14827 { 14828 aLayout = []; 14829 _fnDetectHeader( aLayout, nHeader ); 14830 } 14831 } 14832 14833 for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ ) 14834 { 14835 for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ ) 14836 { 14837 if ( aLayout[i][j].unique && 14838 (!aReturn[j] || !oSettings.bSortCellsTop) ) 14839 { 14840 aReturn[j] = aLayout[i][j].cell; 14841 } 14842 } 14843 } 14844 14845 return aReturn; 14846 } 14847 14848 /** 14849 *
vendor: 19,882 bytes, lines 14849-15508
14849Create an Ajax call based on the table's settings, taking into account that 14850 * parameters can have multiple forms, and backwards compatibility. 14851 * 14852 * @param {object} oSettings dataTables settings object 14853 * @param {array} data Data to send to the server, required by 14854 * DataTables - may be augmented by developer callbacks 14855 * @param {function} fn Callback function to run when data is obtained 14856 */ 14857 function _fnBuildAjax( oSettings, data, fn ) 14858 { 14859 // Compatibility with 1.9-, allow fnServerData and event to manipulate 14860 _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] ); 14861 14862 // Convert to object based for 1.10+ if using the old array scheme which can 14863 // come from server-side processing or serverParams 14864 if ( data && Array.isArray(data) ) { 14865 var tmp = {}; 14866 var rbracket = /(.*?)\[\]$/; 14867 14868 $.each( data, function (key, val) { 14869 var match = val.name.match(rbracket); 14870 14871 if ( match ) { 14872 // Support for arrays 14873 var name = match[0]; 14874 14875 if ( ! tmp[ name ] ) { 14876 tmp[ name ] = []; 14877 } 14878 tmp[ name ].push( val.value ); 14879 } 14880 else { 14881 tmp[val.name] = val.value; 14882 } 14883 } ); 14884 data = tmp; 14885 } 14886 14887 var ajaxData; 14888 var ajax = oSettings.ajax; 14889 var instance = oSettings.oInstance; 14890 var callback = function ( json ) { 14891 var status = oSettings.jqXhr 14892 ? oSettings.jqXhr.status 14893 : null; 14894 14895 if ( json === null || (typeof status === 'number' && status == 204 ) ) { 14896 json = {}; 14897 _fnAjaxDataSrc( oSettings, json, [] ); 14898 } 14899 14900 var error = json.error || json.sError; 14901 if ( error ) { 14902 _fnLog( oSettings, 0, error ); 14903 } 14904 14905 oSettings.json = json; 14906 14907 _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] ); 14908 fn( json ); 14909 }; 14910 14911 if ( $.isPlainObject( ajax ) && ajax.data ) 14912 { 14913 ajaxData = ajax.data; 14914 14915 var newData = typeof ajaxData === 'function' ? 14916 ajaxData( data, oSettings ) : // fn can manipulate data or return 14917 ajaxData; // an object object or array to merge 14918 14919 // If the function returned something, use that alone 14920 data = typeof ajaxData === 'function' && newData ? 14921 newData : 14922 $.extend( true, data, newData ); 14923 14924 // Remove the data property as we've resolved it already and don't want 14925 // jQuery to do it again (it is restored at the end of the function) 14926 delete ajax.data; 14927 } 14928 14929 var baseAjax = { 14930 "data": data, 14931 "success": callback, 14932 "dataType": "json", 14933 "cache": false, 14934 "type": oSettings.sServerMethod, 14935 "error": function (xhr, error, thrown) { 14936 var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] ); 14937 14938 if ( $.inArray( true, ret ) === -1 ) { 14939 if ( error == "parsererror" ) { 14940 _fnLog( oSettings, 0, 'Invalid JSON response', 1 ); 14941 } 14942 else if ( xhr.readyState === 4 ) { 14943 _fnLog( oSettings, 0, 'Ajax error', 7 ); 14944 } 14945 } 14946 14947 _fnProcessingDisplay( oSettings, false ); 14948 } 14949 }; 14950 14951 // Store the data submitted for the API 14952 oSettings.oAjaxData = data; 14953 14954 // Allow plug-ins and external processes to modify the data 14955 _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] ); 14956 14957 if ( oSettings.fnServerData ) 14958 { 14959 // DataTables 1.9- compatibility 14960 oSettings.fnServerData.call( instance, 14961 oSettings.sAjaxSource, 14962 $.map( data, function (val, key) { // Need to convert back to 1.9 trad format 14963 return { name: key, value: val }; 14964 } ), 14965 callback, 14966 oSettings 14967 ); 14968 } 14969 else if ( oSettings.sAjaxSource || typeof ajax === 'string' ) 14970 { 14971 // DataTables 1.9- compatibility 14972 oSettings.jqXHR = $.ajax( $.extend( baseAjax, { 14973 url: ajax || oSettings.sAjaxSource 14974 } ) ); 14975 } 14976 else if ( typeof ajax === 'function' ) 14977 { 14978 // Is a function - let the caller define what needs to be done 14979 oSettings.jqXHR = ajax.call( instance, data, callback, oSettings ); 14980 } 14981 else 14982 { 14983 // Object to extend the base settings 14984 oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) ); 14985 14986 // Restore for next time around 14987 ajax.data = ajaxData; 14988 } 14989 } 14990 14991 14992 /** 14993 * Update the table using an Ajax call 14994 * @param {object} settings dataTables settings object 14995 * @returns {boolean} Block the table drawing or not 14996 * @memberof DataTable#oApi 14997 */ 14998 function _fnAjaxUpdate( settings ) 14999 { 15000 settings.iDraw++; 15001 _fnProcessingDisplay( settings, true ); 15002 15003 _fnBuildAjax( 15004 settings, 15005 _fnAjaxParameters( settings ), 15006 function(json) { 15007 _fnAjaxUpdateDraw( settings, json ); 15008 } 15009 ); 15010 } 15011 15012 15013 /** 15014 * Build up the parameters in an object needed for a server-side processing 15015 * request. Note that this is basically done twice, is different ways - a modern 15016 * method which is used by default in DataTables 1.10 which uses objects and 15017 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if 15018 * the sAjaxSource option is used in the initialisation, or the legacyAjax 15019 * option is set. 15020 * @param {object} oSettings dataTables settings object 15021 * @returns {bool} block the table drawing or not 15022 * @memberof DataTable#oApi 15023 */ 15024 function _fnAjaxParameters( settings ) 15025 { 15026 var 15027 columns = settings.aoColumns, 15028 columnCount = columns.length, 15029 features = settings.oFeatures, 15030 preSearch = settings.oPreviousSearch, 15031 preColSearch = settings.aoPreSearchCols, 15032 i, data = [], dataProp, column, columnSearch, 15033 sort = _fnSortFlatten( settings ), 15034 displayStart = settings._iDisplayStart, 15035 displayLength = features.bPaginate !== false ? 15036 settings._iDisplayLength : 15037 -1; 15038 15039 var param = function ( name, value ) { 15040 data.push( { 'name': name, 'value': value } ); 15041 }; 15042 15043 // DataTables 1.9- compatible method 15044 param( 'sEcho', settings.iDraw ); 15045 param( 'iColumns', columnCount ); 15046 param( 'sColumns', _pluck( columns, 'sName' ).join(',') ); 15047 param( 'iDisplayStart', displayStart ); 15048 param( 'iDisplayLength', displayLength ); 15049 15050 // DataTables 1.10+ method 15051 var d = { 15052 draw: settings.iDraw, 15053 columns: [], 15054 order: [], 15055 start: displayStart, 15056 length: displayLength, 15057 search: { 15058 value: preSearch.sSearch, 15059 regex: preSearch.bRegex 15060 } 15061 }; 15062 15063 for ( i=0 ; i<columnCount ; i++ ) { 15064 column = columns[i]; 15065 columnSearch = preColSearch[i]; 15066 dataProp = typeof column.mData=="function" ? 'function' : column.mData ; 15067 15068 d.columns.push( { 15069 data: dataProp, 15070 name: column.sName, 15071 searchable: column.bSearchable, 15072 orderable: column.bSortable, 15073 search: { 15074 value: columnSearch.sSearch, 15075 regex: columnSearch.bRegex 15076 } 15077 } ); 15078 15079 param( "mDataProp_"+i, dataProp ); 15080 15081 if ( features.bFilter ) { 15082 param( 'sSearch_'+i, columnSearch.sSearch ); 15083 param( 'bRegex_'+i, columnSearch.bRegex ); 15084 param( 'bSearchable_'+i, column.bSearchable ); 15085 } 15086 15087 if ( features.bSort ) { 15088 param( 'bSortable_'+i, column.bSortable ); 15089 } 15090 } 15091 15092 if ( features.bFilter ) { 15093 param( 'sSearch', preSearch.sSearch ); 15094 param( 'bRegex', preSearch.bRegex ); 15095 } 15096 15097 if ( features.bSort ) { 15098 $.each( sort, function ( i, val ) { 15099 d.order.push( { column: val.col, dir: val.dir } ); 15100 15101 param( 'iSortCol_'+i, val.col ); 15102 param( 'sSortDir_'+i, val.dir ); 15103 } ); 15104 15105 param( 'iSortingCols', sort.length ); 15106 } 15107 15108 // If the legacy.ajax parameter is null, then we automatically decide which 15109 // form to use, based on sAjaxSource 15110 var legacy = DataTable.ext.legacy.ajax; 15111 if ( legacy === null ) { 15112 return settings.sAjaxSource ? data : d; 15113 } 15114 15115 // Otherwise, if legacy has been specified then we use that to decide on the 15116 // form 15117 return legacy ? data : d; 15118 } 15119 15120 15121 /** 15122 * Data the data from the server (nuking the old) and redraw the table 15123 * @param {object} oSettings dataTables settings object 15124 * @param {object} json json data return from the server. 15125 * @param {string} json.sEcho Tracking flag for DataTables to match requests 15126 * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering 15127 * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering 15128 * @param {array} json.aaData The data to display on this page 15129 * @param {string} [json.sColumns] Column ordering (sName, comma separated) 15130 * @memberof DataTable#oApi 15131 */ 15132 function _fnAjaxUpdateDraw ( settings, json ) 15133 { 15134 // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation. 15135 // Support both 15136 var compat = function ( old, modern ) { 15137 return json[old] !== undefined ? json[old] : json[modern]; 15138 }; 15139 15140 var data = _fnAjaxDataSrc( settings, json ); 15141 var draw = compat( 'sEcho', 'draw' ); 15142 var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' ); 15143 var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' ); 15144 15145 if ( draw !== undefined ) { 15146 // Protect against out of sequence returns 15147 if ( draw*1 < settings.iDraw ) { 15148 return; 15149 } 15150 settings.iDraw = draw * 1; 15151 } 15152 15153 // No data in returned object, so rather than an array, we show an empty table 15154 if ( ! data ) { 15155 data = []; 15156 } 15157 15158 _fnClearTable( settings ); 15159 settings._iRecordsTotal = parseInt(recordsTotal, 10); 15160 settings._iRecordsDisplay = parseInt(recordsFiltered, 10); 15161 15162 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 15163 _fnAddData( settings, data[i] ); 15164 } 15165 settings.aiDisplay = settings.aiDisplayMaster.slice(); 15166 15167 _fnDraw( settings, true ); 15168 15169 if ( ! settings._bInitComplete ) { 15170 _fnInitComplete( settings, json ); 15171 } 15172 15173 _fnProcessingDisplay( settings, false ); 15174 } 15175 15176 15177 /** 15178 * Get the data from the JSON data source to use for drawing a table. Using 15179 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the 15180 * source object, or from a processing function. 15181 * @param {object} oSettings dataTables settings object 15182 * @param {object} json Data source object / array from the server 15183 * @return {array} Array of data to use 15184 */ 15185 function _fnAjaxDataSrc ( oSettings, json, write ) 15186 { 15187 var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ? 15188 oSettings.ajax.dataSrc : 15189 oSettings.sAjaxDataProp; // Compatibility with 1.9-. 15190 15191 if ( ! write ) { 15192 if ( dataSrc === 'data' ) { 15193 // If the default, then we still want to support the old style, and safely ignore 15194 // it if possible 15195 return json.aaData || json[dataSrc]; 15196 } 15197 15198 return dataSrc !== "" ? 15199 _fnGetObjectDataFn( dataSrc )( json ) : 15200 json; 15201 } 15202 15203 // set 15204 _fnSetObjectDataFn( dataSrc )( json, write ); 15205 } 15206 15207 /** 15208 * Generate the node required for filtering text 15209 * @returns {node} Filter control element 15210 * @param {object} oSettings dataTables settings object 15211 * @memberof DataTable#oApi 15212 */ 15213 function _fnFeatureHtmlFilter ( settings ) 15214 { 15215 var classes = settings.oClasses; 15216 var tableId = settings.sTableId; 15217 var language = settings.oLanguage; 15218 var previousSearch = settings.oPreviousSearch; 15219 var features = settings.aanFeatures; 15220 var input = '<input type="search" class="'+classes.sFilterInput+'"/>'; 15221 15222 var str = language.sSearch; 15223 str = str.match(/_INPUT_/) ? 15224 str.replace('_INPUT_', input) : 15225 str+input; 15226 15227 var filter = $('<div/>', { 15228 'id': ! features.f ? tableId+'_filter' : null, 15229 'class': classes.sFilter 15230 } ) 15231 .append( $('<label/>' ).append( str ) ); 15232 15233 var searchFn = function(event) { 15234 /* Update all other filter input elements for the new display */ 15235 var n = features.f; 15236 var val = !this.value ? "" : this.value; // mental IE8 fix :-( 15237 if(previousSearch.return && event.key !== "Enter") { 15238 return; 15239 } 15240 /* Now do the filter */ 15241 if ( val != previousSearch.sSearch ) { 15242 _fnFilterComplete( settings, { 15243 "sSearch": val, 15244 "bRegex": previousSearch.bRegex, 15245 "bSmart": previousSearch.bSmart , 15246 "bCaseInsensitive": previousSearch.bCaseInsensitive, 15247 "return": previousSearch.return 15248 } ); 15249 15250 // Need to redraw, without resorting 15251 settings._iDisplayStart = 0; 15252 _fnDraw( settings ); 15253 } 15254 }; 15255 15256 var searchDelay = settings.searchDelay !== null ? 15257 settings.searchDelay : 15258 _fnDataSource( settings ) === 'ssp' ? 15259 400 : 15260 0; 15261 15262 var jqFilter = $('input', filter) 15263 .val( previousSearch.sSearch ) 15264 .attr( 'placeholder', language.sSearchPlaceholder ) 15265 .on( 15266 'keyup.DT search.DT input.DT paste.DT cut.DT', 15267 searchDelay ? 15268 _fnThrottle( searchFn, searchDelay ) : 15269 searchFn 15270 ) 15271 .on( 'mouseup', function(e) { 15272 // Edge fix! Edge 17 does not trigger anything other than mouse events when clicking 15273 // on the clear icon (Edge bug 17584515). This is safe in other browsers as `searchFn` 15274 // checks the value to see if it has changed. In other browsers it won't have. 15275 setTimeout( function () { 15276 searchFn.call(jqFilter[0], e); 15277 }, 10); 15278 } ) 15279 .on( 'keypress.DT', function(e) { 15280 /* Prevent form submission */ 15281 if ( e.keyCode == 13 ) { 15282 return false; 15283 } 15284 } ) 15285 .attr('aria-controls', tableId); 15286 15287 // Update the input elements whenever the table is filtered 15288 $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) { 15289 if ( settings === s ) { 15290 // IE9 throws an 'unknown error' if document.activeElement is used 15291 // inside an iframe or frame... 15292 try { 15293 if ( jqFilter[0] !== document.activeElement ) { 15294 jqFilter.val( previousSearch.sSearch ); 15295 } 15296 } 15297 catch ( e ) {} 15298 } 15299 } ); 15300 15301 return filter[0]; 15302 } 15303 15304 15305 /** 15306 * Filter the table using both the global filter and column based filtering 15307 * @param {object} oSettings dataTables settings object 15308 * @param {object} oSearch search information 15309 * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0) 15310 * @memberof DataTable#oApi 15311 */ 15312 function _fnFilterComplete ( oSettings, oInput, iForce ) 15313 { 15314 var oPrevSearch = oSettings.oPreviousSearch; 15315 var aoPrevSearch = oSettings.aoPreSearchCols; 15316 var fnSaveFilter = function ( oFilter ) { 15317 /* Save the filtering values */ 15318 oPrevSearch.sSearch = oFilter.sSearch; 15319 oPrevSearch.bRegex = oFilter.bRegex; 15320 oPrevSearch.bSmart = oFilter.bSmart; 15321 oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive; 15322 oPrevSearch.return = oFilter.return; 15323 }; 15324 var fnRegex = function ( o ) { 15325 // Backwards compatibility with the bEscapeRegex option 15326 return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex; 15327 }; 15328 15329 // Resolve any column types that are unknown due to addition or invalidation 15330 // @todo As per sort - can this be moved into an event handler? 15331 _fnColumnTypes( oSettings ); 15332 15333 /* In server-side processing all filtering is done by the server, so no point hanging around here */ 15334 if ( _fnDataSource( oSettings ) != 'ssp' ) 15335 { 15336 /* Global filter */ 15337 _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive, oInput.return ); 15338 fnSaveFilter( oInput ); 15339 15340 /* Now do the individual column filter */ 15341 for ( var i=0 ; i<aoPrevSearch.length ; i++ ) 15342 { 15343 _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]), 15344 aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive ); 15345 } 15346 15347 /* Custom filtering */ 15348 _fnFilterCustom( oSettings ); 15349 } 15350 else 15351 { 15352 fnSaveFilter( oInput ); 15353 } 15354 15355 /* Tell the draw function we have been filtering */ 15356 oSettings.bFiltered = true; 15357 _fnCallbackFire( oSettings, null, 'search', [oSettings] ); 15358 } 15359 15360 15361 /** 15362 * Apply custom filtering functions 15363 * @param {object} oSettings dataTables settings object 15364 * @memberof DataTable#oApi 15365 */ 15366 function _fnFilterCustom( settings ) 15367 { 15368 var filters = DataTable.ext.search; 15369 var displayRows = settings.aiDisplay; 15370 var row, rowIdx; 15371 15372 for ( var i=0, ien=filters.length ; i<ien ; i++ ) { 15373 var rows = []; 15374 15375 // Loop over each row and see if it should be included 15376 for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) { 15377 rowIdx = displayRows[ j ]; 15378 row = settings.aoData[ rowIdx ]; 15379 15380 if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) { 15381 rows.push( rowIdx ); 15382 } 15383 } 15384 15385 // So the array reference doesn't break set the results into the 15386 // existing array 15387 displayRows.length = 0; 15388 $.merge( displayRows, rows ); 15389 } 15390 } 15391 15392 15393 /** 15394 * Filter the table on a per-column basis 15395 * @param {object} oSettings dataTables settings object 15396 * @param {string} sInput string to filter on 15397 * @param {int} iColumn column to filter 15398 * @param {bool} bRegex treat search string as a regular expression or not 15399 * @param {bool} bSmart use smart filtering or not 15400 * @param {bool} bCaseInsensitive Do case insensitive matching or not 15401 * @memberof DataTable#oApi 15402 */ 15403 function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive ) 15404 { 15405 if ( searchStr === '' ) { 15406 return; 15407 } 15408 15409 var data; 15410 var out = []; 15411 var display = settings.aiDisplay; 15412 var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive ); 15413 15414 for ( var i=0 ; i<display.length ; i++ ) { 15415 data = settings.aoData[ display[i] ]._aFilterData[ colIdx ]; 15416 15417 if ( rpSearch.test( data ) ) { 15418 out.push( display[i] ); 15419 } 15420 } 15421 15422 settings.aiDisplay = out; 15423 } 15424 15425 15426 /** 15427 * Filter the data table based on user input and draw the table 15428 * @param {object} settings dataTables settings object 15429 * @param {string} input string to filter on 15430 * @param {int} force optional - force a research of the master array (1) or not (undefined or 0) 15431 * @param {bool} regex treat as a regular expression or not 15432 * @param {bool} smart perform smart filtering or not 15433 * @param {bool} caseInsensitive Do case insensitive matching or not 15434 * @memberof DataTable#oApi 15435 */ 15436 function _fnFilter( settings, input, force, regex, smart, caseInsensitive ) 15437 { 15438 var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive ); 15439 var prevSearch = settings.oPreviousSearch.sSearch; 15440 var displayMaster = settings.aiDisplayMaster; 15441 var display, invalidated, i; 15442 var filtered = []; 15443 15444 // Need to take account of custom filtering functions - always filter 15445 if ( DataTable.ext.search.length !== 0 ) { 15446 force = true; 15447 } 15448 15449 // Check if any of the rows were invalidated 15450 invalidated = _fnFilterData( settings ); 15451 15452 // If the input is blank - we just want the full data set 15453 if ( input.length <= 0 ) { 15454 settings.aiDisplay = displayMaster.slice(); 15455 } 15456 else { 15457 // New search - start from the master array 15458 if ( invalidated || 15459 force || 15460 regex || 15461 prevSearch.length > input.length || 15462 input.indexOf(prevSearch) !== 0 || 15463 settings.bSorted // On resort, the display master needs to be 15464 // re-filtered since indexes will have changed 15465 ) { 15466 settings.aiDisplay = displayMaster.slice(); 15467 } 15468 15469 // Search the display array 15470 display = settings.aiDisplay; 15471 15472 for ( i=0 ; i<display.length ; i++ ) { 15473 if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) { 15474 filtered.push( display[i] ); 15475 } 15476 } 15477 15478 settings.aiDisplay = filtered; 15479 } 15480 } 15481 15482 15483 /** 15484 * Build a regular expression object suitable for searching a table 15485 * @param {string} sSearch string to search for 15486 * @param {bool} bRegex treat as a regular expression or not 15487 * @param {bool} bSmart perform smart filtering or not 15488 * @param {bool} bCaseInsensitive Do case insensitive matching or not 15489 * @returns {RegExp} constructed object 15490 * @memberof DataTable#oApi 15491 */ 15492 function _fnFilterCreateSearch( search, regex, smart, caseInsensitive ) 15493 { 15494 search = regex ? 15495 search : 15496 _fnEscapeRegex( search ); 15497 15498 if ( smart ) { 15499 /* For smart filtering we want to allow the search to work regardless of 15500 * word order. We also want double quoted text to be preserved, so word 15501 * order is important - a la google. So this is what we want to 15502 * generate: 15503 * 15504 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$ 15505 */ 15506 var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) { 15507 if ( word.charAt(0) === '"' ) { 15508 var m = word.match( /^"(.*)"
vendor: 13,994 bytes, lines 15508-16041
15508$/ ); 15509 word = m ? m[1] : word; 15510 } 15511 15512 return word.replace('"', ''); 15513 } ); 15514 15515 search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$'; 15516 } 15517 15518 return new RegExp( search, caseInsensitive ? 'i' : '' ); 15519 } 15520 15521 15522 /** 15523 * Escape a string such that it can be used in a regular expression 15524 * @param {string} sVal string to escape 15525 * @returns {string} escaped string 15526 * @memberof DataTable#oApi 15527 */ 15528 var _fnEscapeRegex = DataTable.util.escapeRegex; 15529 15530 var __filter_div = $('<div>')[0]; 15531 var __filter_div_textContent = __filter_div.textContent !== undefined; 15532 15533 // Update the filtering data for each row if needed (by invalidation or first run) 15534 function _fnFilterData ( settings ) 15535 { 15536 var columns = settings.aoColumns; 15537 var column; 15538 var i, j, ien, jen, filterData, cellData, row; 15539 var wasInvalidated = false; 15540 15541 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 15542 row = settings.aoData[i]; 15543 15544 if ( ! row._aFilterData ) { 15545 filterData = []; 15546 15547 for ( j=0, jen=columns.length ; j<jen ; j++ ) { 15548 column = columns[j]; 15549 15550 if ( column.bSearchable ) { 15551 cellData = _fnGetCellData( settings, i, j, 'filter' ); 15552 15553 // Search in DataTables 1.10 is string based. In 1.11 this 15554 // should be altered to also allow strict type checking. 15555 if ( cellData === null ) { 15556 cellData = ''; 15557 } 15558 15559 if ( typeof cellData !== 'string' && cellData.toString ) { 15560 cellData = cellData.toString(); 15561 } 15562 } 15563 else { 15564 cellData = ''; 15565 } 15566 15567 // If it looks like there is an HTML entity in the string, 15568 // attempt to decode it so sorting works as expected. Note that 15569 // we could use a single line of jQuery to do this, but the DOM 15570 // method used here is much faster http://jsperf.com/html-decode 15571 if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) { 15572 __filter_div.innerHTML = cellData; 15573 cellData = __filter_div_textContent ? 15574 __filter_div.textContent : 15575 __filter_div.innerText; 15576 } 15577 15578 if ( cellData.replace ) { 15579 cellData = cellData.replace(/[\r\n\u2028]/g, ''); 15580 } 15581 15582 filterData.push( cellData ); 15583 } 15584 15585 row._aFilterData = filterData; 15586 row._sFilterRow = filterData.join(' '); 15587 wasInvalidated = true; 15588 } 15589 } 15590 15591 return wasInvalidated; 15592 } 15593 15594 15595 /** 15596 * Convert from the internal Hungarian notation to camelCase for external 15597 * interaction 15598 * @param {object} obj Object to convert 15599 * @returns {object} Inverted object 15600 * @memberof DataTable#oApi 15601 */ 15602 function _fnSearchToCamel ( obj ) 15603 { 15604 return { 15605 search: obj.sSearch, 15606 smart: obj.bSmart, 15607 regex: obj.bRegex, 15608 caseInsensitive: obj.bCaseInsensitive 15609 }; 15610 } 15611 15612 15613 15614 /** 15615 * Convert from camelCase notation to the internal Hungarian. We could use the 15616 * Hungarian convert function here, but this is cleaner 15617 * @param {object} obj Object to convert 15618 * @returns {object} Inverted object 15619 * @memberof DataTable#oApi 15620 */ 15621 function _fnSearchToHung ( obj ) 15622 { 15623 return { 15624 sSearch: obj.search, 15625 bSmart: obj.smart, 15626 bRegex: obj.regex, 15627 bCaseInsensitive: obj.caseInsensitive 15628 }; 15629 } 15630 15631 /** 15632 * Generate the node required for the info display 15633 * @param {object} oSettings dataTables settings object 15634 * @returns {node} Information element 15635 * @memberof DataTable#oApi 15636 */ 15637 function _fnFeatureHtmlInfo ( settings ) 15638 { 15639 var 15640 tid = settings.sTableId, 15641 nodes = settings.aanFeatures.i, 15642 n = $('<div/>', { 15643 'class': settings.oClasses.sInfo, 15644 'id': ! nodes ? tid+'_info' : null 15645 } ); 15646 15647 if ( ! nodes ) { 15648 // Update display on each draw 15649 settings.aoDrawCallback.push( { 15650 "fn": _fnUpdateInfo, 15651 "sName": "information" 15652 } ); 15653 15654 n 15655 .attr( 'role', 'status' ) 15656 .attr( 'aria-live', 'polite' ); 15657 15658 // Table is described by our info div 15659 $(settings.nTable).attr( 'aria-describedby', tid+'_info' ); 15660 } 15661 15662 return n[0]; 15663 } 15664 15665 15666 /** 15667 * Update the information elements in the display 15668 * @param {object} settings dataTables settings object 15669 * @memberof DataTable#oApi 15670 */ 15671 function _fnUpdateInfo ( settings ) 15672 { 15673 /* Show information about the table */ 15674 var nodes = settings.aanFeatures.i; 15675 if ( nodes.length === 0 ) { 15676 return; 15677 } 15678 15679 var 15680 lang = settings.oLanguage, 15681 start = settings._iDisplayStart+1, 15682 end = settings.fnDisplayEnd(), 15683 max = settings.fnRecordsTotal(), 15684 total = settings.fnRecordsDisplay(), 15685 out = total ? 15686 lang.sInfo : 15687 lang.sInfoEmpty; 15688 15689 if ( total !== max ) { 15690 /* Record set after filtering */ 15691 out += ' ' + lang.sInfoFiltered; 15692 } 15693 15694 // Convert the macros 15695 out += lang.sInfoPostFix; 15696 out = _fnInfoMacros( settings, out ); 15697 15698 var callback = lang.fnInfoCallback; 15699 if ( callback !== null ) { 15700 out = callback.call( settings.oInstance, 15701 settings, start, end, max, total, out 15702 ); 15703 } 15704 15705 $(nodes).html( out ); 15706 } 15707 15708 15709 function _fnInfoMacros ( settings, str ) 15710 { 15711 // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only 15712 // internally 15713 var 15714 formatter = settings.fnFormatNumber, 15715 start = settings._iDisplayStart+1, 15716 len = settings._iDisplayLength, 15717 vis = settings.fnRecordsDisplay(), 15718 all = len === -1; 15719 15720 return str. 15721 replace(/_START_/g, formatter.call( settings, start ) ). 15722 replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ). 15723 replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ). 15724 replace(/_TOTAL_/g, formatter.call( settings, vis ) ). 15725 replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ). 15726 replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) ); 15727 } 15728 15729 15730 15731 /** 15732 * Draw the table for the first time, adding all required features 15733 * @param {object} settings dataTables settings object 15734 * @memberof DataTable#oApi 15735 */ 15736 function _fnInitialise ( settings ) 15737 { 15738 var i, iLen, iAjaxStart=settings.iInitDisplayStart; 15739 var columns = settings.aoColumns, column; 15740 var features = settings.oFeatures; 15741 var deferLoading = settings.bDeferLoading; // value modified by the draw 15742 15743 /* Ensure that the table data is fully initialised */ 15744 if ( ! settings.bInitialised ) { 15745 setTimeout( function(){ _fnInitialise( settings ); }, 200 ); 15746 return; 15747 } 15748 15749 /* Show the display HTML options */ 15750 _fnAddOptionsHtml( settings ); 15751 15752 /* Build and draw the header / footer for the table */ 15753 _fnBuildHead( settings ); 15754 _fnDrawHead( settings, settings.aoHeader ); 15755 _fnDrawHead( settings, settings.aoFooter ); 15756 15757 /* Okay to show that something is going on now */ 15758 _fnProcessingDisplay( settings, true ); 15759 15760 /* Calculate sizes for columns */ 15761 if ( features.bAutoWidth ) { 15762 _fnCalculateColumnWidths( settings ); 15763 } 15764 15765 for ( i=0, iLen=columns.length ; i<iLen ; i++ ) { 15766 column = columns[i]; 15767 15768 if ( column.sWidth ) { 15769 column.nTh.style.width = _fnStringToCss( column.sWidth ); 15770 } 15771 } 15772 15773 _fnCallbackFire( settings, null, 'preInit', [settings] ); 15774 15775 // If there is default sorting required - let's do it. The sort function 15776 // will do the drawing for us. Otherwise we draw the table regardless of the 15777 // Ajax source - this allows the table to look initialised for Ajax sourcing 15778 // data (show 'loading' message possibly) 15779 _fnReDraw( settings ); 15780 15781 // Server-side processing init complete is done by _fnAjaxUpdateDraw 15782 var dataSrc = _fnDataSource( settings ); 15783 if ( dataSrc != 'ssp' || deferLoading ) { 15784 // if there is an ajax source load the data 15785 if ( dataSrc == 'ajax' ) { 15786 _fnBuildAjax( settings, [], function(json) { 15787 var aData = _fnAjaxDataSrc( settings, json ); 15788 15789 // Got the data - add it to the table 15790 for ( i=0 ; i<aData.length ; i++ ) { 15791 _fnAddData( settings, aData[i] ); 15792 } 15793 15794 // Reset the init display for cookie saving. We've already done 15795 // a filter, and therefore cleared it before. So we need to make 15796 // it appear 'fresh' 15797 settings.iInitDisplayStart = iAjaxStart; 15798 15799 _fnReDraw( settings ); 15800 15801 _fnProcessingDisplay( settings, false ); 15802 _fnInitComplete( settings, json ); 15803 }, settings ); 15804 } 15805 else { 15806 _fnProcessingDisplay( settings, false ); 15807 _fnInitComplete( settings ); 15808 } 15809 } 15810 } 15811 15812 15813 /** 15814 * Draw the table for the first time, adding all required features 15815 * @param {object} oSettings dataTables settings object 15816 * @param {object} [json] JSON from the server that completed the table, if using Ajax source 15817 * with client-side processing (optional) 15818 * @memberof DataTable#oApi 15819 */ 15820 function _fnInitComplete ( settings, json ) 15821 { 15822 settings._bInitComplete = true; 15823 15824 // When data was added after the initialisation (data or Ajax) we need to 15825 // calculate the column sizing 15826 if ( json || settings.oInit.aaData ) { 15827 _fnAdjustColumnSizing( settings ); 15828 } 15829 15830 _fnCallbackFire( settings, null, 'plugin-init', [settings, json] ); 15831 _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] ); 15832 } 15833 15834 15835 function _fnLengthChange ( settings, val ) 15836 { 15837 var len = parseInt( val, 10 ); 15838 settings._iDisplayLength = len; 15839 15840 _fnLengthOverflow( settings ); 15841 15842 // Fire length change event 15843 _fnCallbackFire( settings, null, 'length', [settings, len] ); 15844 } 15845 15846 15847 /** 15848 * Generate the node required for user display length changing 15849 * @param {object} settings dataTables settings object 15850 * @returns {node} Display length feature node 15851 * @memberof DataTable#oApi 15852 */ 15853 function _fnFeatureHtmlLength ( settings ) 15854 { 15855 var 15856 classes = settings.oClasses, 15857 tableId = settings.sTableId, 15858 menu = settings.aLengthMenu, 15859 d2 = Array.isArray( menu[0] ), 15860 lengths = d2 ? menu[0] : menu, 15861 language = d2 ? menu[1] : menu; 15862 15863 var select = $('<select/>', { 15864 'name': tableId+'_length', 15865 'aria-controls': tableId, 15866 'class': classes.sLengthSelect 15867 } ); 15868 15869 for ( var i=0, ien=lengths.length ; i<ien ; i++ ) { 15870 select[0][ i ] = new Option( 15871 typeof language[i] === 'number' ? 15872 settings.fnFormatNumber( language[i] ) : 15873 language[i], 15874 lengths[i] 15875 ); 15876 } 15877 15878 var div = $('<div><label/></div>').addClass( classes.sLength ); 15879 if ( ! settings.aanFeatures.l ) { 15880 div[0].id = tableId+'_length'; 15881 } 15882 15883 div.children().append( 15884 settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML ) 15885 ); 15886 15887 // Can't use `select` variable as user might provide their own and the 15888 // reference is broken by the use of outerHTML 15889 $('select', div) 15890 .val( settings._iDisplayLength ) 15891 .on( 'change.DT', function(e) { 15892 _fnLengthChange( settings, $(this).val() ); 15893 _fnDraw( settings ); 15894 } ); 15895 15896 // Update node value whenever anything changes the table's length 15897 $(settings.nTable).on( 'length.dt.DT', function (e, s, len) { 15898 if ( settings === s ) { 15899 $('select', div).val( len ); 15900 } 15901 } ); 15902 15903 return div[0]; 15904 } 15905 15906 15907 15908 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 15909 * Note that most of the paging logic is done in 15910 * DataTable.ext.pager 15911 */ 15912 15913 /** 15914 * Generate the node required for default pagination 15915 * @param {object} oSettings dataTables settings object 15916 * @returns {node} Pagination feature node 15917 * @memberof DataTable#oApi 15918 */ 15919 function _fnFeatureHtmlPaginate ( settings ) 15920 { 15921 var 15922 type = settings.sPaginationType, 15923 plugin = DataTable.ext.pager[ type ], 15924 modern = typeof plugin === 'function', 15925 redraw = function( settings ) { 15926 _fnDraw( settings ); 15927 }, 15928 node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0], 15929 features = settings.aanFeatures; 15930 15931 if ( ! modern ) { 15932 plugin.fnInit( settings, node, redraw ); 15933 } 15934 15935 /* Add a draw callback for the pagination on first instance, to update the paging display */ 15936 if ( ! features.p ) 15937 { 15938 node.id = settings.sTableId+'_paginate'; 15939 15940 settings.aoDrawCallback.push( { 15941 "fn": function( settings ) { 15942 if ( modern ) { 15943 var 15944 start = settings._iDisplayStart, 15945 len = settings._iDisplayLength, 15946 visRecords = settings.fnRecordsDisplay(), 15947 all = len === -1, 15948 page = all ? 0 : Math.ceil( start / len ), 15949 pages = all ? 1 : Math.ceil( visRecords / len ), 15950 buttons = plugin(page, pages), 15951 i, ien; 15952 15953 for ( i=0, ien=features.p.length ; i<ien ; i++ ) { 15954 _fnRenderer( settings, 'pageButton' )( 15955 settings, features.p[i], i, buttons, page, pages 15956 ); 15957 } 15958 } 15959 else { 15960 plugin.fnUpdate( settings, redraw ); 15961 } 15962 }, 15963 "sName": "pagination" 15964 } ); 15965 } 15966 15967 return node; 15968 } 15969 15970 15971 /** 15972 * Alter the display settings to change the page 15973 * @param {object} settings DataTables settings object 15974 * @param {string|int} action Paging action to take: "first", "previous", 15975 * "next" or "last" or page number to jump to (integer) 15976 * @param [bool] redraw Automatically draw the update or not 15977 * @returns {bool} true page has changed, false - no change 15978 * @memberof DataTable#oApi 15979 */ 15980 function _fnPageChange ( settings, action, redraw ) 15981 { 15982 var 15983 start = settings._iDisplayStart, 15984 len = settings._iDisplayLength, 15985 records = settings.fnRecordsDisplay(); 15986 15987 if ( records === 0 || len === -1 ) 15988 { 15989 start = 0; 15990 } 15991 else if ( typeof action === "number" ) 15992 { 15993 start = action * len; 15994 15995 if ( start > records ) 15996 { 15997 start = 0; 15998 } 15999 } 16000 else if ( action == "first" ) 16001 { 16002 start = 0; 16003 } 16004 else if ( action == "previous" ) 16005 { 16006 start = len >= 0 ? 16007 start - len : 16008 0; 16009 16010 if ( start < 0 ) 16011 { 16012 start = 0; 16013 } 16014 } 16015 else if ( action == "next" ) 16016 { 16017 if ( start + len < records ) 16018 { 16019 start += len; 16020 } 16021 } 16022 else if ( action == "last" ) 16023 { 16024 start = Math.floor( (records-1) / len) * len; 16025 } 16026 else 16027 { 16028 _fnLog( settings, 0, "Unknown paging action: "+action, 5 ); 16029 } 16030 16031 var changed = settings._iDisplayStart !== start; 16032 settings._iDisplayStart = start; 16033 16034 if ( changed ) { 16035 _fnCallbackFire( settings, null, 'page', [settings] ); 16036 16037 if ( redraw ) { 16038 _fnDraw( settings ); 16039 } 16040 } 16041
16041 16042 return changed; 16043 } 16044 16045 16046 16047 /** 16048 * Generate the node required for the processing node 16049 * @param {object} settings dataTables settings object 16050 * @returns {node} Processing element 16051 * @memberof DataTable#oApi 16052 */ 16053 function _fnFeatureHtmlProcessing ( settings ) 16054 { 16055 return $('<div/>', { 16056 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null, 16057 'class': settings.oClasses.sProcessing 16058 } ) 16059 .html( settings.oLanguage.sProcessing
vendor: 7,187 bytes, lines 16059-16309
16059) 16060 .insertBefore( settings.nTable )[0]; 16061 } 16062 16063 16064 /** 16065 * Display or hide the processing indicator 16066 * @param {object} settings dataTables settings object 16067 * @param {bool} show Show the processing indicator (true) or not (false) 16068 * @memberof DataTable#oApi 16069 */ 16070 function _fnProcessingDisplay ( settings, show ) 16071 { 16072 if ( settings.oFeatures.bProcessing ) { 16073 $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' ); 16074 } 16075 16076 _fnCallbackFire( settings, null, 'processing', [settings, show] ); 16077 } 16078 16079 /** 16080 * Add any control elements for the table - specifically scrolling 16081 * @param {object} settings dataTables settings object 16082 * @returns {node} Node to add to the DOM 16083 * @memberof DataTable#oApi 16084 */ 16085 function _fnFeatureHtmlTable ( settings ) 16086 { 16087 var table = $(settings.nTable); 16088 16089 // Scrolling from here on in 16090 var scroll = settings.oScroll; 16091 16092 if ( scroll.sX === '' && scroll.sY === '' ) { 16093 return settings.nTable; 16094 } 16095 16096 var scrollX = scroll.sX; 16097 var scrollY = scroll.sY; 16098 var classes = settings.oClasses; 16099 var caption = table.children('caption'); 16100 var captionSide = caption.length ? caption[0]._captionSide : null; 16101 var headerClone = $( table[0].cloneNode(false) ); 16102 var footerClone = $( table[0].cloneNode(false) ); 16103 var footer = table.children('tfoot'); 16104 var _div = '<div/>'; 16105 var size = function ( s ) { 16106 return !s ? null : _fnStringToCss( s ); 16107 }; 16108 16109 if ( ! footer.length ) { 16110 footer = null; 16111 } 16112 16113 /* 16114 * The HTML structure that we want to generate in this function is: 16115 * div - scroller 16116 * div - scroll head 16117 * div - scroll head inner 16118 * table - scroll head table 16119 * thead - thead 16120 * div - scroll body 16121 * table - table (master table) 16122 * thead - thead clone for sizing 16123 * tbody - tbody 16124 * div - scroll foot 16125 * div - scroll foot inner 16126 * table - scroll foot table 16127 * tfoot - tfoot 16128 */ 16129 var scroller = $( _div, { 'class': classes.sScrollWrapper } ) 16130 .append( 16131 $(_div, { 'class': classes.sScrollHead } ) 16132 .css( { 16133 overflow: 'hidden', 16134 position: 'relative', 16135 border: 0, 16136 width: scrollX ? size(scrollX) : '100%' 16137 } ) 16138 .append( 16139 $(_div, { 'class': classes.sScrollHeadInner } ) 16140 .css( { 16141 'box-sizing': 'content-box', 16142 width: scroll.sXInner || '100%' 16143 } ) 16144 .append( 16145 headerClone 16146 .removeAttr('id') 16147 .css( 'margin-left', 0 ) 16148 .append( captionSide === 'top' ? caption : null ) 16149 .append( 16150 table.children('thead') 16151 ) 16152 ) 16153 ) 16154 ) 16155 .append( 16156 $(_div, { 'class': classes.sScrollBody } ) 16157 .css( { 16158 position: 'relative', 16159 overflow: 'auto', 16160 width: size( scrollX ) 16161 } ) 16162 .append( table ) 16163 ); 16164 16165 if ( footer ) { 16166 scroller.append( 16167 $(_div, { 'class': classes.sScrollFoot } ) 16168 .css( { 16169 overflow: 'hidden', 16170 border: 0, 16171 width: scrollX ? size(scrollX) : '100%' 16172 } ) 16173 .append( 16174 $(_div, { 'class': classes.sScrollFootInner } ) 16175 .append( 16176 footerClone 16177 .removeAttr('id') 16178 .css( 'margin-left', 0 ) 16179 .append( captionSide === 'bottom' ? caption : null ) 16180 .append( 16181 table.children('tfoot') 16182 ) 16183 ) 16184 ) 16185 ); 16186 } 16187 16188 var children = scroller.children(); 16189 var scrollHead = children[0]; 16190 var scrollBody = children[1]; 16191 var scrollFoot = footer ? children[2] : null; 16192 16193 // When the body is scrolled, then we also want to scroll the headers 16194 if ( scrollX ) { 16195 $(scrollBody).on( 'scroll.DT', function (e) { 16196 var scrollLeft = this.scrollLeft; 16197 16198 scrollHead.scrollLeft = scrollLeft; 16199 16200 if ( footer ) { 16201 scrollFoot.scrollLeft = scrollLeft; 16202 } 16203 } ); 16204 } 16205 16206 $(scrollBody).css('max-height', scrollY); 16207 if (! scroll.bCollapse) { 16208 $(scrollBody).css('height', scrollY); 16209 } 16210 16211 settings.nScrollHead = scrollHead; 16212 settings.nScrollBody = scrollBody; 16213 settings.nScrollFoot = scrollFoot; 16214 16215 // On redraw - align columns 16216 settings.aoDrawCallback.push( { 16217 "fn": _fnScrollDraw, 16218 "sName": "scrolling" 16219 } ); 16220 16221 return scroller[0]; 16222 } 16223 16224 16225 16226 /** 16227 * Update the header, footer and body tables for resizing - i.e. column 16228 * alignment. 16229 * 16230 * Welcome to the most horrible function DataTables. The process that this 16231 * function follows is basically: 16232 * 1. Re-create the table inside the scrolling div 16233 * 2. Take live measurements from the DOM 16234 * 3. Apply the measurements to align the columns 16235 * 4. Clean up 16236 * 16237 * @param {object} settings dataTables settings object 16238 * @memberof DataTable#oApi 16239 */ 16240 function _fnScrollDraw ( settings ) 16241 { 16242 // Given that this is such a monster function, a lot of variables are use 16243 // to try and keep the minimised size as small as possible 16244 var 16245 scroll = settings.oScroll, 16246 scrollX = scroll.sX, 16247 scrollXInner = scroll.sXInner, 16248 scrollY = scroll.sY, 16249 barWidth = scroll.iBarWidth, 16250 divHeader = $(settings.nScrollHead), 16251 divHeaderStyle = divHeader[0].style, 16252 divHeaderInner = divHeader.children('div'), 16253 divHeaderInnerStyle = divHeaderInner[0].style, 16254 divHeaderTable = divHeaderInner.children('table'), 16255 divBodyEl = settings.nScrollBody, 16256 divBody = $(divBodyEl), 16257 divBodyStyle = divBodyEl.style, 16258 divFooter = $(settings.nScrollFoot), 16259 divFooterInner = divFooter.children('div'), 16260 divFooterTable = divFooterInner.children('table'), 16261 header = $(settings.nTHead), 16262 table = $(settings.nTable), 16263 tableEl = table[0], 16264 tableStyle = tableEl.style, 16265 footer = settings.nTFoot ? $(settings.nTFoot) : null, 16266 browser = settings.oBrowser, 16267 ie67 = browser.bScrollOversize, 16268 dtHeaderCells = _pluck( settings.aoColumns, 'nTh' ), 16269 headerTrgEls, footerTrgEls, 16270 headerSrcEls, footerSrcEls, 16271 headerCopy, footerCopy, 16272 headerWidths=[], footerWidths=[], 16273 headerContent=[], footerContent=[], 16274 idx, correction, sanityWidth, 16275 zeroOut = function(nSizer) { 16276 var style = nSizer.style; 16277 style.paddingTop = "0"; 16278 style.paddingBottom = "0"; 16279 style.borderTopWidth = "0"; 16280 style.borderBottomWidth = "0"; 16281 style.height = 0; 16282 }; 16283 16284 // If the scrollbar visibility has changed from the last draw, we need to 16285 // adjust the column sizes as the table width will have changed to account 16286 // for the scrollbar 16287 var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight; 16288 16289 if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) { 16290 settings.scrollBarVis = scrollBarVis; 16291 _fnAdjustColumnSizing( settings ); 16292 return; // adjust column sizing will call this function again 16293 } 16294 else { 16295 settings.scrollBarVis = scrollBarVis; 16296 } 16297 16298 /* 16299 * 1. Re-create the table inside the scrolling div 16300 */ 16301 16302 // Remove the old minimised thead and tfoot elements in the inner table 16303 table.children('thead, tfoot').remove(); 16304 16305 if ( footer ) { 16306 footerCopy = footer.clone().prependTo( table ); 16307 footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized 16308 footerSrcEls = footerCopy.find('tr'); 16309
vendor: 4,075 bytes, lines 16309-16436
16309} 16310 16311 // Clone the current header and footer elements and then place it into the inner table 16312 headerCopy = header.clone().prependTo( table ); 16313 headerTrgEls = header.find('tr'); // original header is in its own table 16314 headerSrcEls = headerCopy.find('tr'); 16315 headerCopy.find('th, td').removeAttr('tabindex'); 16316 16317 16318 /* 16319 * 2. Take live measurements from the DOM - do not alter the DOM itself! 16320 */ 16321 16322 // Remove old sizing and apply the calculated column widths 16323 // Get the unique column headers in the newly created (cloned) header. We want to apply the 16324 // calculated sizes to this header 16325 if ( ! scrollX ) 16326 { 16327 divBodyStyle.width = '100%'; 16328 divHeader[0].style.width = '100%'; 16329 } 16330 16331 $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) { 16332 idx = _fnVisibleToColumnIndex( settings, i ); 16333 el.style.width = settings.aoColumns[idx].sWidth; 16334 } ); 16335 16336 if ( footer ) { 16337 _fnApplyToChildren( function(n) { 16338 n.style.width = ""; 16339 }, footerSrcEls ); 16340 } 16341 16342 // Size the table as a whole 16343 sanityWidth = table.outerWidth(); 16344 if ( scrollX === "" ) { 16345 // No x scrolling 16346 tableStyle.width = "100%"; 16347 16348 // IE7 will make the width of the table when 100% include the scrollbar 16349 // - which is shouldn't. When there is a scrollbar we need to take this 16350 // into account. 16351 if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight || 16352 divBody.css('overflow-y') == "scroll") 16353 ) { 16354 tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth); 16355 } 16356 16357 // Recalculate the sanity width 16358 sanityWidth = table.outerWidth(); 16359 } 16360 else if ( scrollXInner !== "" ) { 16361 // legacy x scroll inner has been given - use it 16362 tableStyle.width = _fnStringToCss(scrollXInner); 16363 16364 // Recalculate the sanity width 16365 sanityWidth = table.outerWidth(); 16366 } 16367 16368 // Hidden header should have zero height, so remove padding and borders. Then 16369 // set the width based on the real headers 16370 16371 // Apply all styles in one pass 16372 _fnApplyToChildren( zeroOut, headerSrcEls ); 16373 16374 // Read all widths in next pass 16375 _fnApplyToChildren( function(nSizer) { 16376 var style = window.getComputedStyle ? 16377 window.getComputedStyle(nSizer).width : 16378 _fnStringToCss( $(nSizer).width() ); 16379 16380 headerContent.push( nSizer.innerHTML ); 16381 headerWidths.push( style ); 16382 }, headerSrcEls ); 16383 16384 // Apply all widths in final pass 16385 _fnApplyToChildren( function(nToSize, i) { 16386 nToSize.style.width = headerWidths[i]; 16387 }, headerTrgEls ); 16388 16389 $(headerSrcEls).height(0); 16390 16391 /* Same again with the footer if we have one */ 16392 if ( footer ) 16393 { 16394 _fnApplyToChildren( zeroOut, footerSrcEls ); 16395 16396 _fnApplyToChildren( function(nSizer) { 16397 footerContent.push( nSizer.innerHTML ); 16398 footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) ); 16399 }, footerSrcEls ); 16400 16401 _fnApplyToChildren( function(nToSize, i) { 16402 nToSize.style.width = footerWidths[i]; 16403 }, footerTrgEls ); 16404 16405 $(footerSrcEls).height(0); 16406 } 16407 16408 16409 /* 16410 * 3. Apply the measurements 16411 */ 16412 16413 // "Hide" the header and footer that we used for the sizing. We need to keep 16414 // the content of the cell so that the width applied to the header and body 16415 // both match, but we want to hide it completely. We want to also fix their 16416 // width to what they currently are 16417 _fnApplyToChildren( function(nSizer, i) { 16418 nSizer.innerHTML = '<div class="dataTables_sizing">'+headerContent[i]+'</div>'; 16419 nSizer.childNodes[0].style.height = "0"; 16420 nSizer.childNodes[0].style.overflow = "hidden"; 16421 nSizer.style.width = headerWidths[i]; 16422 }, headerSrcEls ); 16423 16424 if ( footer ) 16425 { 16426 _fnApplyToChildren( function(nSizer, i) { 16427 nSizer.innerHTML = '<div class="dataTables_sizing">'+footerContent[i]+'</div>'; 16428 nSizer.childNodes[0].style.height = "0"; 16429 nSizer.childNodes[0].style.overflow = "hidden"; 16430 nSizer.style.width = footerWidths[i]; 16431 }, footerSrcEls ); 16432 } 16433 16434 // Sanity check that the table is of a sensible width. If not then we are going to get 16435 // misalignment - try to prevent this by not allowing the table to shrink below its min width 16436 if ( table.outerWidth() < sanityWidth
vendor: 29,265 bytes, lines 16436-17442
16436 ) 16437 { 16438 // The min width depends upon if we have a vertical scrollbar visible or not */ 16439 correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight || 16440 divBody.css('overflow-y') == "scroll")) ? 16441 sanityWidth+barWidth : 16442 sanityWidth; 16443 16444 // IE6/7 are a law unto themselves... 16445 if ( ie67 && (divBodyEl.scrollHeight > 16446 divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll") 16447 ) { 16448 tableStyle.width = _fnStringToCss( correction-barWidth ); 16449 } 16450 16451 // And give the user a warning that we've stopped the table getting too small 16452 if ( scrollX === "" || scrollXInner !== "" ) { 16453 _fnLog( settings, 1, 'Possible column misalignment', 6 ); 16454 } 16455 } 16456 else 16457 { 16458 correction = '100%'; 16459 } 16460 16461 // Apply to the container elements 16462 divBodyStyle.width = _fnStringToCss( correction ); 16463 divHeaderStyle.width = _fnStringToCss( correction ); 16464 16465 if ( footer ) { 16466 settings.nScrollFoot.style.width = _fnStringToCss( correction ); 16467 } 16468 16469 16470 /* 16471 * 4. Clean up 16472 */ 16473 if ( ! scrollY ) { 16474 /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting 16475 * the scrollbar height from the visible display, rather than adding it on. We need to 16476 * set the height in order to sort this. Don't want to do it in any other browsers. 16477 */ 16478 if ( ie67 ) { 16479 divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth ); 16480 } 16481 } 16482 16483 /* Finally set the width's of the header and footer tables */ 16484 var iOuterWidth = table.outerWidth(); 16485 divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth ); 16486 divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth ); 16487 16488 // Figure out if there are scrollbar present - if so then we need a the header and footer to 16489 // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) 16490 var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll"; 16491 var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' ); 16492 divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px"; 16493 16494 if ( footer ) { 16495 divFooterTable[0].style.width = _fnStringToCss( iOuterWidth ); 16496 divFooterInner[0].style.width = _fnStringToCss( iOuterWidth ); 16497 divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px"; 16498 } 16499 16500 // Correct DOM ordering for colgroup - comes before the thead 16501 table.children('colgroup').insertBefore( table.children('thead') ); 16502 16503 /* Adjust the position of the header in case we loose the y-scrollbar */ 16504 divBody.trigger('scroll'); 16505 16506 // If sorting or filtering has occurred, jump the scrolling back to the top 16507 // only if we aren't holding the position 16508 if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) { 16509 divBodyEl.scrollTop = 0; 16510 } 16511 } 16512 16513 16514 16515 /** 16516 * Apply a given function to the display child nodes of an element array (typically 16517 * TD children of TR rows 16518 * @param {function} fn Method to apply to the objects 16519 * @param array {nodes} an1 List of elements to look through for display children 16520 * @param array {nodes} an2 Another list (identical structure to the first) - optional 16521 * @memberof DataTable#oApi 16522 */ 16523 function _fnApplyToChildren( fn, an1, an2 ) 16524 { 16525 var index=0, i=0, iLen=an1.length; 16526 var nNode1, nNode2; 16527 16528 while ( i < iLen ) { 16529 nNode1 = an1[i].firstChild; 16530 nNode2 = an2 ? an2[i].firstChild : null; 16531 16532 while ( nNode1 ) { 16533 if ( nNode1.nodeType === 1 ) { 16534 if ( an2 ) { 16535 fn( nNode1, nNode2, index ); 16536 } 16537 else { 16538 fn( nNode1, index ); 16539 } 16540 16541 index++; 16542 } 16543 16544 nNode1 = nNode1.nextSibling; 16545 nNode2 = an2 ? nNode2.nextSibling : null; 16546 } 16547 16548 i++; 16549 } 16550 } 16551 16552 16553 16554 var __re_html_remove = /<.*?>/g; 16555 16556 16557 /** 16558 * Calculate the width of columns for the table 16559 * @param {object} oSettings dataTables settings object 16560 * @memberof DataTable#oApi 16561 */ 16562 function _fnCalculateColumnWidths ( oSettings ) 16563 { 16564 var 16565 table = oSettings.nTable, 16566 columns = oSettings.aoColumns, 16567 scroll = oSettings.oScroll, 16568 scrollY = scroll.sY, 16569 scrollX = scroll.sX, 16570 scrollXInner = scroll.sXInner, 16571 columnCount = columns.length, 16572 visibleColumns = _fnGetColumns( oSettings, 'bVisible' ), 16573 headerCells = $('th', oSettings.nTHead), 16574 tableWidthAttr = table.getAttribute('width'), // from DOM element 16575 tableContainer = table.parentNode, 16576 userInputs = false, 16577 i, column, columnIdx, width, outerWidth, 16578 browser = oSettings.oBrowser, 16579 ie67 = browser.bScrollOversize; 16580 16581 var styleWidth = table.style.width; 16582 if ( styleWidth && styleWidth.indexOf('%') !== -1 ) { 16583 tableWidthAttr = styleWidth; 16584 } 16585 16586 /* Convert any user input sizes into pixel sizes */ 16587 for ( i=0 ; i<visibleColumns.length ; i++ ) { 16588 column = columns[ visibleColumns[i] ]; 16589 16590 if ( column.sWidth !== null ) { 16591 column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer ); 16592 16593 userInputs = true; 16594 } 16595 } 16596 16597 /* If the number of columns in the DOM equals the number that we have to 16598 * process in DataTables, then we can use the offsets that are created by 16599 * the web- browser. No custom sizes can be set in order for this to happen, 16600 * nor scrolling used 16601 */ 16602 if ( ie67 || ! userInputs && ! scrollX && ! scrollY && 16603 columnCount == _fnVisbleColumns( oSettings ) && 16604 columnCount == headerCells.length 16605 ) { 16606 for ( i=0 ; i<columnCount ; i++ ) { 16607 var colIdx = _fnVisibleToColumnIndex( oSettings, i ); 16608 16609 if ( colIdx !== null ) { 16610 columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() ); 16611 } 16612 } 16613 } 16614 else 16615 { 16616 // Otherwise construct a single row, worst case, table with the widest 16617 // node in the data, assign any user defined widths, then insert it into 16618 // the DOM and allow the browser to do all the hard work of calculating 16619 // table widths 16620 var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table 16621 .css( 'visibility', 'hidden' ) 16622 .removeAttr( 'id' ); 16623 16624 // Clean up the table body 16625 tmpTable.find('tbody tr').remove(); 16626 var tr = $('<tr/>').appendTo( tmpTable.find('tbody') ); 16627 16628 // Clone the table header and footer - we can't use the header / footer 16629 // from the cloned table, since if scrolling is active, the table's 16630 // real header and footer are contained in different table tags 16631 tmpTable.find('thead, tfoot').remove(); 16632 tmpTable 16633 .append( $(oSettings.nTHead).clone() ) 16634 .append( $(oSettings.nTFoot).clone() ); 16635 16636 // Remove any assigned widths from the footer (from scrolling) 16637 tmpTable.find('tfoot th, tfoot td').css('width', ''); 16638 16639 // Apply custom sizing to the cloned header 16640 headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] ); 16641 16642 for ( i=0 ; i<visibleColumns.length ; i++ ) { 16643 column = columns[ visibleColumns[i] ]; 16644 16645 headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ? 16646 _fnStringToCss( column.sWidthOrig ) : 16647 ''; 16648 16649 // For scrollX we need to force the column width otherwise the 16650 // browser will collapse it. If this width is smaller than the 16651 // width the column requires, then it will have no effect 16652 if ( column.sWidthOrig && scrollX ) { 16653 $( headerCells[i] ).append( $('<div/>').css( { 16654 width: column.sWidthOrig, 16655 margin: 0, 16656 padding: 0, 16657 border: 0, 16658 height: 1 16659 } ) ); 16660 } 16661 } 16662 16663 // Find the widest cell for each column and put it into the table 16664 if ( oSettings.aoData.length ) { 16665 for ( i=0 ; i<visibleColumns.length ; i++ ) { 16666 columnIdx = visibleColumns[i]; 16667 column = columns[ columnIdx ]; 16668 16669 $( _fnGetWidestNode( oSettings, columnIdx ) ) 16670 .clone( false ) 16671 .append( column.sContentPadding ) 16672 .appendTo( tr ); 16673 } 16674 } 16675 16676 // Tidy the temporary table - remove name attributes so there aren't 16677 // duplicated in the dom (radio elements for example) 16678 $('[name]', tmpTable).removeAttr('name'); 16679 16680 // Table has been built, attach to the document so we can work with it. 16681 // A holding element is used, positioned at the top of the container 16682 // with minimal height, so it has no effect on if the container scrolls 16683 // or not. Otherwise it might trigger scrolling when it actually isn't 16684 // needed 16685 var holder = $('<div/>').css( scrollX || scrollY ? 16686 { 16687 position: 'absolute', 16688 top: 0, 16689 left: 0, 16690 height: 1, 16691 right: 0, 16692 overflow: 'hidden' 16693 } : 16694 {} 16695 ) 16696 .append( tmpTable ) 16697 .appendTo( tableContainer ); 16698 16699 // When scrolling (X or Y) we want to set the width of the table as 16700 // appropriate. However, when not scrolling leave the table width as it 16701 // is. This results in slightly different, but I think correct behaviour 16702 if ( scrollX && scrollXInner ) { 16703 tmpTable.width( scrollXInner ); 16704 } 16705 else if ( scrollX ) { 16706 tmpTable.css( 'width', 'auto' ); 16707 tmpTable.removeAttr('width'); 16708 16709 // If there is no width attribute or style, then allow the table to 16710 // collapse 16711 if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) { 16712 tmpTable.width( tableContainer.clientWidth ); 16713 } 16714 } 16715 else if ( scrollY ) { 16716 tmpTable.width( tableContainer.clientWidth ); 16717 } 16718 else if ( tableWidthAttr ) { 16719 tmpTable.width( tableWidthAttr ); 16720 } 16721 16722 // Get the width of each column in the constructed table - we need to 16723 // know the inner width (so it can be assigned to the other table's 16724 // cells) and the outer width so we can calculate the full width of the 16725 // table. This is safe since DataTables requires a unique cell for each 16726 // column, but if ever a header can span multiple columns, this will 16727 // need to be modified. 16728 var total = 0; 16729 for ( i=0 ; i<visibleColumns.length ; i++ ) { 16730 var cell = $(headerCells[i]); 16731 var border = cell.outerWidth() - cell.width(); 16732 16733 // Use getBounding... where possible (not IE8-) because it can give 16734 // sub-pixel accuracy, which we then want to round up! 16735 var bounding = browser.bBounding ? 16736 Math.ceil( headerCells[i].getBoundingClientRect().width ) : 16737 cell.outerWidth(); 16738 16739 // Total is tracked to remove any sub-pixel errors as the outerWidth 16740 // of the table might not equal the total given here (IE!). 16741 total += bounding; 16742 16743 // Width for each column to use 16744 columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border ); 16745 } 16746 16747 table.style.width = _fnStringToCss( total ); 16748 16749 // Finished with the table - ditch it 16750 holder.remove(); 16751 } 16752 16753 // If there is a width attr, we want to attach an event listener which 16754 // allows the table sizing to automatically adjust when the window is 16755 // resized. Use the width attr rather than CSS, since we can't know if the 16756 // CSS is a relative value or absolute - DOM read is always px. 16757 if ( tableWidthAttr ) { 16758 table.style.width = _fnStringToCss( tableWidthAttr ); 16759 } 16760 16761 if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) { 16762 var bindResize = function () { 16763 $(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () { 16764 _fnAdjustColumnSizing( oSettings ); 16765 } ) ); 16766 }; 16767 16768 // IE6/7 will crash if we bind a resize event handler on page load. 16769 // To be removed in 1.11 which drops IE6/7 support 16770 if ( ie67 ) { 16771 setTimeout( bindResize, 1000 ); 16772 } 16773 else { 16774 bindResize(); 16775 } 16776 16777 oSettings._reszEvt = true; 16778 } 16779 } 16780 16781 16782 /** 16783 * Throttle the calls to a function. Arguments and context are maintained for 16784 * the throttled function 16785 * @param {function} fn Function to be called 16786 * @param {int} [freq=200] call frequency in mS 16787 * @returns {function} wrapped function 16788 * @memberof DataTable#oApi 16789 */ 16790 var _fnThrottle = DataTable.util.throttle; 16791 16792 16793 /** 16794 * Convert a CSS unit width to pixels (e.g. 2em) 16795 * @param {string} width width to be converted 16796 * @param {node} parent parent to get the with for (required for relative widths) - optional 16797 * @returns {int} width in pixels 16798 * @memberof DataTable#oApi 16799 */ 16800 function _fnConvertToWidth ( width, parent ) 16801 { 16802 if ( ! width ) { 16803 return 0; 16804 } 16805 16806 var n = $('<div/>') 16807 .css( 'width', _fnStringToCss( width ) ) 16808 .appendTo( parent || document.body ); 16809 16810 var val = n[0].offsetWidth; 16811 n.remove(); 16812 16813 return val; 16814 } 16815 16816 16817 /** 16818 * Get the widest node 16819 * @param {object} settings dataTables settings object 16820 * @param {int} colIdx column of interest 16821 * @returns {node} widest table node 16822 * @memberof DataTable#oApi 16823 */ 16824 function _fnGetWidestNode( settings, colIdx ) 16825 { 16826 var idx = _fnGetMaxLenString( settings, colIdx ); 16827 if ( idx < 0 ) { 16828 return null; 16829 } 16830 16831 var data = settings.aoData[ idx ]; 16832 return ! data.nTr ? // Might not have been created when deferred rendering 16833 $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] : 16834 data.anCells[ colIdx ]; 16835 } 16836 16837 16838 /** 16839 * Get the maximum strlen for each data column 16840 * @param {object} settings dataTables settings object 16841 * @param {int} colIdx column of interest 16842 * @returns {string} max string length for each column 16843 * @memberof DataTable#oApi 16844 */ 16845 function _fnGetMaxLenString( settings, colIdx ) 16846 { 16847 var s, max=-1, maxIdx = -1; 16848 16849 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 16850 s = _fnGetCellData( settings, i, colIdx, 'display' )+''; 16851 s = s.replace( __re_html_remove, '' ); 16852 s = s.replace( / /g, ' ' ); 16853 16854 if ( s.length > max ) { 16855 max = s.length; 16856 maxIdx = i; 16857 } 16858 } 16859 16860 return maxIdx; 16861 } 16862 16863 16864 /** 16865 * Append a CSS unit (only if required) to a string 16866 * @param {string} value to css-ify 16867 * @returns {string} value with css unit 16868 * @memberof DataTable#oApi 16869 */ 16870 function _fnStringToCss( s ) 16871 { 16872 if ( s === null ) { 16873 return '0px'; 16874 } 16875 16876 if ( typeof s == 'number' ) { 16877 return s < 0 ? 16878 '0px' : 16879 s+'px'; 16880 } 16881 16882 // Check it has a unit character already 16883 return s.match(/\d$/) ? 16884 s+'px' : 16885 s; 16886 } 16887 16888 16889 16890 function _fnSortFlatten ( settings ) 16891 { 16892 var 16893 i, iLen, k, kLen, 16894 aSort = [], 16895 aiOrig = [], 16896 aoColumns = settings.aoColumns, 16897 aDataSort, iCol, sType, srcCol, 16898 fixed = settings.aaSortingFixed, 16899 fixedObj = $.isPlainObject( fixed ), 16900 nestedSort = [], 16901 add = function ( a ) { 16902 if ( a.length && ! Array.isArray( a[0] ) ) { 16903 // 1D array 16904 nestedSort.push( a ); 16905 } 16906 else { 16907 // 2D array 16908 $.merge( nestedSort, a ); 16909 } 16910 }; 16911 16912 // Build the sort array, with pre-fix and post-fix options if they have been 16913 // specified 16914 if ( Array.isArray( fixed ) ) { 16915 add( fixed ); 16916 } 16917 16918 if ( fixedObj && fixed.pre ) { 16919 add( fixed.pre ); 16920 } 16921 16922 add( settings.aaSorting ); 16923 16924 if (fixedObj && fixed.post ) { 16925 add( fixed.post ); 16926 } 16927 16928 for ( i=0 ; i<nestedSort.length ; i++ ) 16929 { 16930 srcCol = nestedSort[i][0]; 16931 aDataSort = aoColumns[ srcCol ].aDataSort; 16932 16933 for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ ) 16934 { 16935 iCol = aDataSort[k]; 16936 sType = aoColumns[ iCol ].sType || 'string'; 16937 16938 if ( nestedSort[i]._idx === undefined ) { 16939 nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting ); 16940 } 16941 16942 aSort.push( { 16943 src: srcCol, 16944 col: iCol, 16945 dir: nestedSort[i][1], 16946 index: nestedSort[i]._idx, 16947 type: sType, 16948 formatter: DataTable.ext.type.order[ sType+"-pre" ] 16949 } ); 16950 } 16951 } 16952 16953 return aSort; 16954 } 16955 16956 /** 16957 * Change the order of the table 16958 * @param {object} oSettings dataTables settings object 16959 * @memberof DataTable#oApi 16960 * @todo This really needs split up! 16961 */ 16962 function _fnSort ( oSettings ) 16963 { 16964 var 16965 i, ien, iLen, j, jLen, k, kLen, 16966 sDataType, nTh, 16967 aiOrig = [], 16968 oExtSort = DataTable.ext.type.order, 16969 aoData = oSettings.aoData, 16970 aoColumns = oSettings.aoColumns, 16971 aDataSort, data, iCol, sType, oSort, 16972 formatters = 0, 16973 sortCol, 16974 displayMaster = oSettings.aiDisplayMaster, 16975 aSort; 16976 16977 // Resolve any column types that are unknown due to addition or invalidation 16978 // @todo Can this be moved into a 'data-ready' handler which is called when 16979 // data is going to be used in the table? 16980 _fnColumnTypes( oSettings ); 16981 16982 aSort = _fnSortFlatten( oSettings ); 16983 16984 for ( i=0, ien=aSort.length ; i<ien ; i++ ) { 16985 sortCol = aSort[i]; 16986 16987 // Track if we can use the fast sort algorithm 16988 if ( sortCol.formatter ) { 16989 formatters++; 16990 } 16991 16992 // Load the data needed for the sort, for each cell 16993 _fnSortData( oSettings, sortCol.col ); 16994 } 16995 16996 /* No sorting required if server-side or no sorting array */ 16997 if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 ) 16998 { 16999 // Create a value - key array of the current row positions such that we can use their 17000 // current position during the sort, if values match, in order to perform stable sorting 17001 for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) { 17002 aiOrig[ displayMaster[i] ] = i; 17003 } 17004 17005 /* Do the sort - here we want multi-column sorting based on a given data source (column) 17006 * and sorting function (from oSort) in a certain direction. It's reasonably complex to 17007 * follow on it's own, but this is what we want (example two column sorting): 17008 * fnLocalSorting = function(a,b){ 17009 * var iTest; 17010 * iTest = oSort['string-asc']('data11', 'data12'); 17011 * if (iTest !== 0) 17012 * return iTest; 17013 * iTest = oSort['numeric-desc']('data21', 'data22'); 17014 * if (iTest !== 0) 17015 * return iTest; 17016 * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] ); 17017 * } 17018 * Basically we have a test for each sorting column, if the data in that column is equal, 17019 * test the next column. If all columns match, then we use a numeric sort on the row 17020 * positions in the original data array to provide a stable sort. 17021 * 17022 * Note - I know it seems excessive to have two sorting methods, but the first is around 17023 * 15% faster, so the second is only maintained for backwards compatibility with sorting 17024 * methods which do not have a pre-sort formatting function. 17025 */ 17026 if ( formatters === aSort.length ) { 17027 // All sort types have formatting functions 17028 displayMaster.sort( function ( a, b ) { 17029 var 17030 x, y, k, test, sort, 17031 len=aSort.length, 17032 dataA = aoData[a]._aSortData, 17033 dataB = aoData[b]._aSortData; 17034 17035 for ( k=0 ; k<len ; k++ ) { 17036 sort = aSort[k]; 17037 17038 x = dataA[ sort.col ]; 17039 y = dataB[ sort.col ]; 17040 17041 test = x<y ? -1 : x>y ? 1 : 0; 17042 if ( test !== 0 ) { 17043 return sort.dir === 'asc' ? test : -test; 17044 } 17045 } 17046 17047 x = aiOrig[a]; 17048 y = aiOrig[b]; 17049 return x<y ? -1 : x>y ? 1 : 0; 17050 } ); 17051 } 17052 else { 17053 // Depreciated - remove in 1.11 (providing a plug-in option) 17054 // Not all sort types have formatting methods, so we have to call their sorting 17055 // methods. 17056 displayMaster.sort( function ( a, b ) { 17057 var 17058 x, y, k, l, test, sort, fn, 17059 len=aSort.length, 17060 dataA = aoData[a]._aSortData, 17061 dataB = aoData[b]._aSortData; 17062 17063 for ( k=0 ; k<len ; k++ ) { 17064 sort = aSort[k]; 17065 17066 x = dataA[ sort.col ]; 17067 y = dataB[ sort.col ]; 17068 17069 fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ]; 17070 test = fn( x, y ); 17071 if ( test !== 0 ) { 17072 return test; 17073 } 17074 } 17075 17076 x = aiOrig[a]; 17077 y = aiOrig[b]; 17078 return x<y ? -1 : x>y ? 1 : 0; 17079 } ); 17080 } 17081 } 17082 17083 /* Tell the draw function that we have sorted the data */ 17084 oSettings.bSorted = true; 17085 } 17086 17087 17088 function _fnSortAria ( settings ) 17089 { 17090 var label; 17091 var nextSort; 17092 var columns = settings.aoColumns; 17093 var aSort = _fnSortFlatten( settings ); 17094 var oAria = settings.oLanguage.oAria; 17095 17096 // ARIA attributes - need to loop all columns, to update all (removing old 17097 // attributes as needed) 17098 for ( var i=0, iLen=columns.length ; i<iLen ; i++ ) 17099 { 17100 var col = columns[i]; 17101 var asSorting = col.asSorting; 17102 var sTitle = col.ariaTitle || col.sTitle.replace( /<.*?>/g, "" ); 17103 var th = col.nTh; 17104 17105 // IE7 is throwing an error when setting these properties with jQuery's 17106 // attr() and removeAttr() methods... 17107 th.removeAttribute('aria-sort'); 17108 17109 /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ 17110 if ( col.bSortable ) { 17111 if ( aSort.length > 0 && aSort[0].col == i ) { 17112 th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" ); 17113 nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0]; 17114 } 17115 else { 17116 nextSort = asSorting[0]; 17117 } 17118 17119 label = sTitle + ( nextSort === "asc" ? 17120 oAria.sSortAscending : 17121 oAria.sSortDescending 17122 ); 17123 } 17124 else { 17125 label = sTitle; 17126 } 17127 17128 th.setAttribute('aria-label', label); 17129 } 17130 } 17131 17132 17133 /** 17134 * Function to run on user sort request 17135 * @param {object} settings dataTables settings object 17136 * @param {node} attachTo node to attach the handler to 17137 * @param {int} colIdx column sorting index 17138 * @param {boolean} [append=false] Append the requested sort to the existing 17139 * sort if true (i.e. multi-column sort) 17140 * @param {function} [callback] callback function 17141 * @memberof DataTable#oApi 17142 */ 17143 function _fnSortListener ( settings, colIdx, append, callback ) 17144 { 17145 var col = settings.aoColumns[ colIdx ]; 17146 var sorting = settings.aaSorting; 17147 var asSorting = col.asSorting; 17148 var nextSortIdx; 17149 var next = function ( a, overflow ) { 17150 var idx = a._idx; 17151 if ( idx === undefined ) { 17152 idx = $.inArray( a[1], asSorting ); 17153 } 17154 17155 return idx+1 < asSorting.length ? 17156 idx+1 : 17157 overflow ? 17158 null : 17159 0; 17160 }; 17161 17162 // Convert to 2D array if needed 17163 if ( typeof sorting[0] === 'number' ) { 17164 sorting = settings.aaSorting = [ sorting ]; 17165 } 17166 17167 // If appending the sort then we are multi-column sorting 17168 if ( append && settings.oFeatures.bSortMulti ) { 17169 // Are we already doing some kind of sort on this column? 17170 var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') ); 17171 17172 if ( sortIdx !== -1 ) { 17173 // Yes, modify the sort 17174 nextSortIdx = next( sorting[sortIdx], true ); 17175 17176 if ( nextSortIdx === null && sorting.length === 1 ) { 17177 nextSortIdx = 0; // can't remove sorting completely 17178 } 17179 17180 if ( nextSortIdx === null ) { 17181 sorting.splice( sortIdx, 1 ); 17182 } 17183 else { 17184 sorting[sortIdx][1] = asSorting[ nextSortIdx ]; 17185 sorting[sortIdx]._idx = nextSortIdx; 17186 } 17187 } 17188 else { 17189 // No sort on this column yet 17190 sorting.push( [ colIdx, asSorting[0], 0 ] ); 17191 sorting[sorting.length-1]._idx = 0; 17192 } 17193 } 17194 else if ( sorting.length && sorting[0][0] == colIdx ) { 17195 // Single column - already sorting on this column, modify the sort 17196 nextSortIdx = next( sorting[0] ); 17197 17198 sorting.length = 1; 17199 sorting[0][1] = asSorting[ nextSortIdx ]; 17200 sorting[0]._idx = nextSortIdx; 17201 } 17202 else { 17203 // Single column - sort only on this column 17204 sorting.length = 0; 17205 sorting.push( [ colIdx, asSorting[0] ] ); 17206 sorting[0]._idx = 0; 17207 } 17208 17209 // Run the sort by calling a full redraw 17210 _fnReDraw( settings ); 17211 17212 // callback used for async user interaction 17213 if ( typeof callback == 'function' ) { 17214 callback( settings ); 17215 } 17216 } 17217 17218 17219 /** 17220 * Attach a sort handler (click) to a node 17221 * @param {object} settings dataTables settings object 17222 * @param {node} attachTo node to attach the handler to 17223 * @param {int} colIdx column sorting index 17224 * @param {function} [callback] callback function 17225 * @memberof DataTable#oApi 17226 */ 17227 function _fnSortAttachListener ( settings, attachTo, colIdx, callback ) 17228 { 17229 var col = settings.aoColumns[ colIdx ]; 17230 17231 _fnBindAction( attachTo, {}, function (e) { 17232 /* If the column is not sortable - don't to anything */ 17233 if ( col.bSortable === false ) { 17234 return; 17235 } 17236 17237 // If processing is enabled use a timeout to allow the processing 17238 // display to be shown - otherwise to it synchronously 17239 if ( settings.oFeatures.bProcessing ) { 17240 _fnProcessingDisplay( settings, true ); 17241 17242 setTimeout( function() { 17243 _fnSortListener( settings, colIdx, e.shiftKey, callback ); 17244 17245 // In server-side processing, the draw callback will remove the 17246 // processing display 17247 if ( _fnDataSource( settings ) !== 'ssp' ) { 17248 _fnProcessingDisplay( settings, false ); 17249 } 17250 }, 0 ); 17251 } 17252 else { 17253 _fnSortListener( settings, colIdx, e.shiftKey, callback ); 17254 } 17255 } ); 17256 } 17257 17258 17259 /** 17260 * Set the sorting classes on table's body, Note: it is safe to call this function 17261 * when bSort and bSortClasses are false 17262 * @param {object} oSettings dataTables settings object 17263 * @memberof DataTable#oApi 17264 */ 17265 function _fnSortingClasses( settings ) 17266 { 17267 var oldSort = settings.aLastSort; 17268 var sortClass = settings.oClasses.sSortColumn; 17269 var sort = _fnSortFlatten( settings ); 17270 var features = settings.oFeatures; 17271 var i, ien, colIdx; 17272 17273 if ( features.bSort && features.bSortClasses ) { 17274 // Remove old sorting classes 17275 for ( i=0, ien=oldSort.length ; i<ien ; i++ ) { 17276 colIdx = oldSort[i].src; 17277 17278 // Remove column sorting 17279 $( _pluck( settings.aoData, 'anCells', colIdx ) ) 17280 .removeClass( sortClass + (i<2 ? i+1 : 3) ); 17281 } 17282 17283 // Add new column sorting 17284 for ( i=0, ien=sort.length ; i<ien ; i++ ) { 17285 colIdx = sort[i].src; 17286 17287 $( _pluck( settings.aoData, 'anCells', colIdx ) ) 17288 .addClass( sortClass + (i<2 ? i+1 : 3) ); 17289 } 17290 } 17291 17292 settings.aLastSort = sort; 17293 } 17294 17295 17296 // Get the data to sort a column, be it from cache, fresh (populating the 17297 // cache), or from a sort formatter 17298 function _fnSortData( settings, idx ) 17299 { 17300 // Custom sorting function - provided by the sort data type 17301 var column = settings.aoColumns[ idx ]; 17302 var customSort = DataTable.ext.order[ column.sSortDataType ]; 17303 var customData; 17304 17305 if ( customSort ) { 17306 customData = customSort.call( settings.oInstance, settings, idx, 17307 _fnColumnIndexToVisible( settings, idx ) 17308 ); 17309 } 17310 17311 // Use / populate cache 17312 var row, cellData; 17313 var formatter = DataTable.ext.type.order[ column.sType+"-pre" ]; 17314 17315 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 17316 row = settings.aoData[i]; 17317 17318 if ( ! row._aSortData ) { 17319 row._aSortData = []; 17320 } 17321 17322 if ( ! row._aSortData[idx] || customSort ) { 17323 cellData = customSort ? 17324 customData[i] : // If there was a custom sort function, use data from there 17325 _fnGetCellData( settings, i, idx, 'sort' ); 17326 17327 row._aSortData[ idx ] = formatter ? 17328 formatter( cellData ) : 17329 cellData; 17330 } 17331 } 17332 } 17333 17334 17335 17336 /** 17337 * Save the state of a table 17338 * @param {object} oSettings dataTables settings object 17339 * @memberof DataTable#oApi 17340 */ 17341 function _fnSaveState ( settings ) 17342 { 17343 if (settings._bLoadingState) { 17344 return; 17345 } 17346 17347 /* Store the interesting variables */ 17348 var state = { 17349 time: +new Date(), 17350 start: settings._iDisplayStart, 17351 length: settings._iDisplayLength, 17352 order: $.extend( true, [], settings.aaSorting ), 17353 search: _fnSearchToCamel( settings.oPreviousSearch ), 17354 columns: $.map( settings.aoColumns, function ( col, i ) { 17355 return { 17356 visible: col.bVisible, 17357 search: _fnSearchToCamel( settings.aoPreSearchCols[i] ) 17358 }; 17359 } ) 17360 }; 17361 17362 settings.oSavedState = state; 17363 _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] ); 17364 17365 if ( settings.oFeatures.bStateSave && !settings.bDestroying ) 17366 { 17367 settings.fnStateSaveCallback.call( settings.oInstance, settings, state ); 17368 } 17369 } 17370 17371 17372 /** 17373 * Attempt to load a saved table state 17374 * @param {object} oSettings dataTables settings object 17375 * @param {object} oInit DataTables init object so we can override settings 17376 * @param {function} callback Callback to execute when the state has been loaded 17377 * @memberof DataTable#oApi 17378 */ 17379 function _fnLoadState ( settings, oInit, callback ) 17380 { 17381 if ( ! settings.oFeatures.bStateSave ) { 17382 callback(); 17383 return; 17384 } 17385 17386 var loaded = function(state) { 17387 _fnImplementState(settings, state, callback); 17388 } 17389 17390 var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded ); 17391 17392 if ( state !== undefined ) { 17393 _fnImplementState( settings, state, callback ); 17394 } 17395 // otherwise, wait for the loaded callback to be executed 17396 17397 return true; 17398 } 17399 17400 function _fnImplementState ( settings, s, callback) { 17401 var i, ien; 17402 var columns = settings.aoColumns; 17403 settings._bLoadingState = true; 17404 17405 // When StateRestore was introduced the state could now be implemented at any time 17406 // Not just initialisation. To do this an api instance is required in some places 17407 var api = settings._bInitComplete ? new DataTable.Api(settings) : null; 17408 17409 if ( ! s || ! s.time ) { 17410 settings._bLoadingState = false; 17411 callback(); 17412 return; 17413 } 17414 17415 // Allow custom and plug-in manipulation functions to alter the saved data set and 17416 // cancelling of loading by returning false 17417 var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] ); 17418 if ( $.inArray( false, abStateLoad ) !== -1 ) { 17419 settings._bLoadingState = false; 17420 callback(); 17421 return; 17422 } 17423 17424 // Reject old data 17425 var duration = settings.iStateDuration; 17426 if ( duration > 0 && s.time < +new Date() - (duration*1000) ) { 17427 settings._bLoadingState = false; 17428 callback(); 17429 return; 17430 } 17431 17432 // Number of columns have changed - all bets are off, no restore of settings 17433 if ( s.columns && columns.length !== s.columns.length ) { 17434 settings._bLoadingState = false; 17435 callback(); 17436 return; 17437 } 17438 17439 // Store the saved state so it might be accessed at any time 17440 settings.oLoadedState = $.extend( true, {}, s ); 17441 17442 //
vendor: 13,462 bytes, lines 17442-17918
17442Restore key features - todo - for 1.11 this needs to be done by 17443 // subscribed events 17444 if ( s.start !== undefined ) { 17445 settings._iDisplayStart = s.start; 17446 if(api === null) { 17447 settings.iInitDisplayStart = s.start; 17448 } 17449 } 17450 if ( s.length !== undefined ) { 17451 settings._iDisplayLength = s.length; 17452 } 17453 17454 // Order 17455 if ( s.order !== undefined ) { 17456 settings.aaSorting = []; 17457 $.each( s.order, function ( i, col ) { 17458 settings.aaSorting.push( col[0] >= columns.length ? 17459 [ 0, col[1] ] : 17460 col 17461 ); 17462 } ); 17463 } 17464 17465 // Search 17466 if ( s.search !== undefined ) { 17467 $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) ); 17468 } 17469 17470 // Columns 17471 if ( s.columns ) { 17472 for ( i=0, ien=s.columns.length ; i<ien ; i++ ) { 17473 var col = s.columns[i]; 17474 17475 // Visibility 17476 if ( col.visible !== undefined ) { 17477 // If the api is defined, the table has been initialised so we need to use it rather than internal settings 17478 if (api) { 17479 // Don't redraw the columns on every iteration of this loop, we will do this at the end instead 17480 api.column(i).visible(col.visible, false); 17481 } 17482 else { 17483 columns[i].bVisible = col.visible; 17484 } 17485 } 17486 17487 // Search 17488 if ( col.search !== undefined ) { 17489 $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) ); 17490 } 17491 } 17492 17493 // If the api is defined then we need to adjust the columns once the visibility has been changed 17494 if (api) { 17495 api.columns.adjust(); 17496 } 17497 } 17498 17499 settings._bLoadingState = false; 17500 _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] ); 17501 callback(); 17502 }; 17503 17504 17505 /** 17506 * Return the settings object for a particular table 17507 * @param {node} table table we are using as a dataTable 17508 * @returns {object} Settings object - or null if not found 17509 * @memberof DataTable#oApi 17510 */ 17511 function _fnSettingsFromNode ( table ) 17512 { 17513 var settings = DataTable.settings; 17514 var idx = $.inArray( table, _pluck( settings, 'nTable' ) ); 17515 17516 return idx !== -1 ? 17517 settings[ idx ] : 17518 null; 17519 } 17520 17521 17522 /** 17523 * Log an error message 17524 * @param {object} settings dataTables settings object 17525 * @param {int} level log error messages, or display them to the user 17526 * @param {string} msg error message 17527 * @param {int} tn Technical note id to get more information about the error. 17528 * @memberof DataTable#oApi 17529 */ 17530 function _fnLog( settings, level, msg, tn ) 17531 { 17532 msg = 'DataTables warning: '+ 17533 (settings ? 'table id='+settings.sTableId+' - ' : '')+msg; 17534 17535 if ( tn ) { 17536 msg += '. For more information about this error, please see '+ 17537 'http://datatables.net/tn/'+tn; 17538 } 17539 17540 if ( ! level ) { 17541 // Backwards compatibility pre 1.10 17542 var ext = DataTable.ext; 17543 var type = ext.sErrMode || ext.errMode; 17544 17545 if ( settings ) { 17546 _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] ); 17547 } 17548 17549 if ( type == 'alert' ) { 17550 alert( msg ); 17551 } 17552 else if ( type == 'throw' ) { 17553 throw new Error(msg); 17554 } 17555 else if ( typeof type == 'function' ) { 17556 type( settings, tn, msg ); 17557 } 17558 } 17559 else if ( window.console && console.log ) { 17560 console.log( msg ); 17561 } 17562 } 17563 17564 17565 /** 17566 * See if a property is defined on one object, if so assign it to the other object 17567 * @param {object} ret target object 17568 * @param {object} src source object 17569 * @param {string} name property 17570 * @param {string} [mappedName] name to map too - optional, name used if not given 17571 * @memberof DataTable#oApi 17572 */ 17573 function _fnMap( ret, src, name, mappedName ) 17574 { 17575 if ( Array.isArray( name ) ) { 17576 $.each( name, function (i, val) { 17577 if ( Array.isArray( val ) ) { 17578 _fnMap( ret, src, val[0], val[1] ); 17579 } 17580 else { 17581 _fnMap( ret, src, val ); 17582 } 17583 } ); 17584 17585 return; 17586 } 17587 17588 if ( mappedName === undefined ) { 17589 mappedName = name; 17590 } 17591 17592 if ( src[name] !== undefined ) { 17593 ret[mappedName] = src[name]; 17594 } 17595 } 17596 17597 17598 /** 17599 * Extend objects - very similar to jQuery.extend, but deep copy objects, and 17600 * shallow copy arrays. The reason we need to do this, is that we don't want to 17601 * deep copy array init values (such as aaSorting) since the dev wouldn't be 17602 * able to override them, but we do want to deep copy arrays. 17603 * @param {object} out Object to extend 17604 * @param {object} extender Object from which the properties will be applied to 17605 * out 17606 * @param {boolean} breakRefs If true, then arrays will be sliced to take an 17607 * independent copy with the exception of the `data` or `aaData` parameters 17608 * if they are present. This is so you can pass in a collection to 17609 * DataTables and have that used as your data source without breaking the 17610 * references 17611 * @returns {object} out Reference, just for convenience - out === the return. 17612 * @memberof DataTable#oApi 17613 * @todo This doesn't take account of arrays inside the deep copied objects. 17614 */ 17615 function _fnExtend( out, extender, breakRefs ) 17616 { 17617 var val; 17618 17619 for ( var prop in extender ) { 17620 if ( extender.hasOwnProperty(prop) ) { 17621 val = extender[prop]; 17622 17623 if ( $.isPlainObject( val ) ) { 17624 if ( ! $.isPlainObject( out[prop] ) ) { 17625 out[prop] = {}; 17626 } 17627 $.extend( true, out[prop], val ); 17628 } 17629 else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && Array.isArray(val) ) { 17630 out[prop] = val.slice(); 17631 } 17632 else { 17633 out[prop] = val; 17634 } 17635 } 17636 } 17637 17638 return out; 17639 } 17640 17641 17642 /** 17643 * Bind an event handers to allow a click or return key to activate the callback. 17644 * This is good for accessibility since a return on the keyboard will have the 17645 * same effect as a click, if the element has focus. 17646 * @param {element} n Element to bind the action to 17647 * @param {object} oData Data object to pass to the triggered function 17648 * @param {function} fn Callback function for when the event is triggered 17649 * @memberof DataTable#oApi 17650 */ 17651 function _fnBindAction( n, oData, fn ) 17652 { 17653 $(n) 17654 .on( 'click.DT', oData, function (e) { 17655 $(n).trigger('blur'); // Remove focus outline for mouse users 17656 fn(e); 17657 } ) 17658 .on( 'keypress.DT', oData, function (e){ 17659 if ( e.which === 13 ) { 17660 e.preventDefault(); 17661 fn(e); 17662 } 17663 } ) 17664 .on( 'selectstart.DT', function () { 17665 /* Take the brutal approach to cancelling text selection */ 17666 return false; 17667 } ); 17668 } 17669 17670 17671 /** 17672 * Register a callback function. Easily allows a callback function to be added to 17673 * an array store of callback functions that can then all be called together. 17674 * @param {object} oSettings dataTables settings object 17675 * @param {string} sStore Name of the array storage for the callbacks in oSettings 17676 * @param {function} fn Function to be called back 17677 * @param {string} sName Identifying name for the callback (i.e. a label) 17678 * @memberof DataTable#oApi 17679 */ 17680 function _fnCallbackReg( oSettings, sStore, fn, sName ) 17681 { 17682 if ( fn ) 17683 { 17684 oSettings[sStore].push( { 17685 "fn": fn, 17686 "sName": sName 17687 } ); 17688 } 17689 } 17690 17691 17692 /** 17693 * Fire callback functions and trigger events. Note that the loop over the 17694 * callback array store is done backwards! Further note that you do not want to 17695 * fire off triggers in time sensitive applications (for example cell creation) 17696 * as its slow. 17697 * @param {object} settings dataTables settings object 17698 * @param {string} callbackArr Name of the array storage for the callbacks in 17699 * oSettings 17700 * @param {string} eventName Name of the jQuery custom event to trigger. If 17701 * null no trigger is fired 17702 * @param {array} args Array of arguments to pass to the callback function / 17703 * trigger 17704 * @memberof DataTable#oApi 17705 */ 17706 function _fnCallbackFire( settings, callbackArr, eventName, args ) 17707 { 17708 var ret = []; 17709 17710 if ( callbackArr ) { 17711 ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) { 17712 return val.fn.apply( settings.oInstance, args ); 17713 } ); 17714 } 17715 17716 if ( eventName !== null ) { 17717 var e = $.Event( eventName+'.dt' ); 17718 17719 $(settings.nTable).trigger( e, args ); 17720 17721 ret.push( e.result ); 17722 } 17723 17724 return ret; 17725 } 17726 17727 17728 function _fnLengthOverflow ( settings ) 17729 { 17730 var 17731 start = settings._iDisplayStart, 17732 end = settings.fnDisplayEnd(), 17733 len = settings._iDisplayLength; 17734 17735 /* If we have space to show extra rows (backing up from the end point - then do so */ 17736 if ( start >= end ) 17737 { 17738 start = end - len; 17739 } 17740 17741 // Keep the start record on the current page 17742 start -= (start % len); 17743 17744 if ( len === -1 || start < 0 ) 17745 { 17746 start = 0; 17747 } 17748 17749 settings._iDisplayStart = start; 17750 } 17751 17752 17753 function _fnRenderer( settings, type ) 17754 { 17755 var renderer = settings.renderer; 17756 var host = DataTable.ext.renderer[type]; 17757 17758 if ( $.isPlainObject( renderer ) && renderer[type] ) { 17759 // Specific renderer for this type. If available use it, otherwise use 17760 // the default. 17761 return host[renderer[type]] || host._; 17762 } 17763 else if ( typeof renderer === 'string' ) { 17764 // Common renderer - if there is one available for this type use it, 17765 // otherwise use the default 17766 return host[renderer] || host._; 17767 } 17768 17769 // Use the default 17770 return host._; 17771 } 17772 17773 17774 /** 17775 * Detect the data source being used for the table. Used to simplify the code 17776 * a little (ajax) and to make it compress a little smaller. 17777 * 17778 * @param {object} settings dataTables settings object 17779 * @returns {string} Data source 17780 * @memberof DataTable#oApi 17781 */ 17782 function _fnDataSource ( settings ) 17783 { 17784 if ( settings.oFeatures.bServerSide ) { 17785 return 'ssp'; 17786 } 17787 else if ( settings.ajax || settings.sAjaxSource ) { 17788 return 'ajax'; 17789 } 17790 return 'dom'; 17791 } 17792 17793 17794 17795 17796 /** 17797 * Computed structure of the DataTables API, defined by the options passed to 17798 * `DataTable.Api.register()` when building the API. 17799 * 17800 * The structure is built in order to speed creation and extension of the Api 17801 * objects since the extensions are effectively pre-parsed. 17802 * 17803 * The array is an array of objects with the following structure, where this 17804 * base array represents the Api prototype base: 17805 * 17806 * [ 17807 * { 17808 * name: 'data' -- string - Property name 17809 * val: function () {}, -- function - Api method (or undefined if just an object 17810 * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result 17811 * propExt: [ ... ] -- array - Array of Api object definitions to extend the property 17812 * }, 17813 * { 17814 * name: 'row' 17815 * val: {}, 17816 * methodExt: [ ... ], 17817 * propExt: [ 17818 * { 17819 * name: 'data' 17820 * val: function () {}, 17821 * methodExt: [ ... ], 17822 * propExt: [ ... ] 17823 * }, 17824 * ... 17825 * ] 17826 * } 17827 * ] 17828 * 17829 * @type {Array} 17830 * @ignore 17831 */ 17832 var __apiStruct = []; 17833 17834 17835 /** 17836 * `Array.prototype` reference. 17837 * 17838 * @type object 17839 * @ignore 17840 */ 17841 var __arrayProto = Array.prototype; 17842 17843 17844 /** 17845 * Abstraction for `context` parameter of the `Api` constructor to allow it to 17846 * take several different forms for ease of use. 17847 * 17848 * Each of the input parameter types will be converted to a DataTables settings 17849 * object where possible. 17850 * 17851 * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one 17852 * of: 17853 * 17854 * * `string` - jQuery selector. Any DataTables' matching the given selector 17855 * with be found and used. 17856 * * `node` - `TABLE` node which has already been formed into a DataTable. 17857 * * `jQuery` - A jQuery object of `TABLE` nodes. 17858 * * `object` - DataTables settings object 17859 * * `DataTables.Api` - API instance 17860 * @return {array|null} Matching DataTables settings objects. `null` or 17861 * `undefined` is returned if no matching DataTable is found. 17862 * @ignore 17863 */ 17864 var _toSettings = function ( mixed ) 17865 { 17866 var idx, jq; 17867 var settings = DataTable.settings; 17868 var tables = $.map( settings, function (el, i) { 17869 return el.nTable; 17870 } ); 17871 17872 if ( ! mixed ) { 17873 return []; 17874 } 17875 else if ( mixed.nTable && mixed.oApi ) { 17876 // DataTables settings object 17877 return [ mixed ]; 17878 } 17879 else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) { 17880 // Table node 17881 idx = $.inArray( mixed, tables ); 17882 return idx !== -1 ? [ settings[idx] ] : null; 17883 } 17884 else if ( mixed && typeof mixed.settings === 'function' ) { 17885 return mixed.settings().toArray(); 17886 } 17887 else if ( typeof mixed === 'string' ) { 17888 // jQuery selector 17889 jq = $(mixed); 17890 } 17891 else if ( mixed instanceof $ ) { 17892 // jQuery object (also DataTables instance) 17893 jq = mixed; 17894 } 17895 17896 if ( jq ) { 17897 return jq.map( function(i) { 17898 idx = $.inArray( this, tables ); 17899 return idx !== -1 ? settings[idx] : null; 17900 } ).toArray(); 17901 } 17902 }; 17903 17904 17905 /** 17906 * DataTables API class - used to control and interface with one or more 17907 * DataTables enhanced tables. 17908 * 17909 * The API class is heavily based on jQuery, presenting a chainable interface 17910 * that you can use to interact with tables. Each instance of the API class has 17911 * a "context" - i.e. the tables that it will operate on. This could be a single 17912 * table, all tables on a page or a sub-set thereof. 17913 * 17914 * Additionally the API is designed to allow you to easily work with the data in 17915 * the tables, retrieving and manipulating it as required. This is done by 17916 * presenting the API class as an array like interface. The contents of the 17917 * array depend upon the actions requested by each method (for example 17918 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
17919 * return an array of objects or arrays depending upon your table's 17920 * configuration). The API object has a number of array like methods (`push`, 17921 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`, 17922 * `unique` etc) to assist your working with the data held in a table. 17923 * 17924 * Most methods (those which return an Api instance) are chainable, which means 17925 * the return from a method call also has all of the methods available that the 17926 * top level object had. For example, these two calls are equivalent: 17927 * 17928 * // Not chained 17929 * api.row.add( {...} ); 17930 * api.draw(); 17931 * 17932 * // Chained 17933 * api.row.add( {...} ).draw(); 17934 * 17935 * @class DataTable.Api 17936 * @param {array|object|string|jQuery} context DataTable identifier. This is 17937 * used to define which DataTables enhanced tables this API will operate on. 17938 * Can be one of: 17939 * 17940 * * `string` - jQuery selector. Any DataTables' matching the given selector 17941 * with be found and used. 17942 * * `node` - `TABLE` node which has already been formed into a DataTable. 17943 * * `jQuery` - A jQuery object of `TABLE` nodes. 17944 * * `object` - DataTables settings object 17945 * @param {array} [data] Data to initialise the Api instance with. 17946 * 17947 * @example 17948 * // Direct initialisation during DataTables construction 17949 * var api = $('#example').DataTable(); 17950 * 17951 * @example 17952 * // Initialisation using a DataTables jQuery object 17953 * var api = $('#example').dataTable().api(); 17954 * 17955 * @example 17956 * // Initialisation as a constructor 17957 * var api = new $.fn.DataTable.Api( 'table.dataTable' ); 17958 */ 17959 _Api = function ( context, data ) 17960 { 17961 if ( ! (this instanceof _Api) ) { 17962 return new _Api( context, data ); 17963 } 17964 17965 var settings = []; 17966 var ctxSettings = function ( o ) { 17967 var a = _toSettings( o ); 17968 if ( a ) { 17969 settings.push.apply( settings, a ); 17970 } 17971 }; 17972 17973 if ( Array.isArray( context ) ) { 17974 for ( var i=0, ien=context.length ; i<ien ; i++ ) { 17975 ctxSettings( context[i] ); 17976 } 17977 } 17978 else { 17979 ctxSettings( context ); 17980 } 17981 17982 // Remove duplicates 17983 this.context = _unique( settings ); 17984 17985 // Initial data 17986 if ( data ) { 17987 $.merge( this, data ); 17988 } 17989 17990 // selector 17991 this.selector = { 17992 rows: null, 17993 cols: null, 17994 opts: null 17995 }; 17996 17997 _Api.extend( this, this, __apiStruct ); 17998 }; 17999 18000 DataTable.Api = _Api; 18001 18002 // Don't destroy the existing prototype, just extend it. Required for jQuery 2's 18003 // isPlainObject. 18004 $.extend( _Api.prototype, { 18005 any: function () 18006 { 18007 return this.count() !== 0; 18008 }, 18009 18010 18011 concat: __arrayProto.concat, 18012 18013 18014 context: [], // array of table settings objects 18015 18016 18017 count: function () 18018 { 18019 return this.flatten().length; 18020 }, 18021 18022 18023 each: function ( fn ) 18024 { 18025 for ( var i=0, ien=this.length ; i<ien; i++ ) { 18026 fn.call( this, this[i], i, this ); 18027 } 18028 18029 return this; 18030 }, 18031 18032 18033 eq: function ( idx ) 18034 { 18035 var ctx = this.context; 18036 18037 return ctx.length > idx ? 18038 new _Api( ctx[idx], this[idx] ) : 18039 null; 18040 }, 18041 18042 18043 filter: function ( fn ) 18044 { 18045 var a = []; 18046 18047 if ( __arrayProto.filter ) { 18048 a = __arrayProto.filter.call( this, fn, this ); 18049 } 18050 else { 18051 // Compatibility for browsers without EMCA-252-5 (JS 1.6) 18052 for ( var i=0, ien=this.length ; i<ien ; i++ ) { 18053 if ( fn.call( this, this[i], i, this ) ) { 18054 a.push( this[i] ); 18055 } 18056 } 18057 } 18058 18059 return new _Api( this.context, a ); 18060 }, 18061 18062 18063 flatten: function () 18064 { 18065 var a = []; 18066 return new _Api( this.context, a.concat.apply( a, this.toArray() ) ); 18067 }, 18068 18069 18070 join: __arrayProto.join, 18071 18072 18073 indexOf: __arrayProto.indexOf || function (obj, start) 18074 { 18075 for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) { 18076 if ( this[i] === obj ) { 18077 return i; 18078 } 18079 } 18080 return -1; 18081 }, 18082 18083 iterator: function ( flatten, type, fn, alwaysNew ) { 18084 var 18085 a = [], ret, 18086 i, ien, j, jen, 18087 context = this.context, 18088 rows, items, item, 18089 selector = this.selector; 18090 18091 // Argument shifting 18092 if ( typeof flatten === 'string' ) { 18093 alwaysNew = fn; 18094 fn = type; 18095 type = flatten; 18096 flatten = false; 18097 } 18098 18099 for ( i=0, ien=context.length ; i<ien ; i++ ) { 18100 var apiInst = new _Api( context[i] ); 18101 18102 if ( type === 'table' ) { 18103 ret = fn.call( apiInst, context[i], i ); 18104 18105 if ( ret !== undefined ) { 18106 a.push( ret ); 18107 } 18108 } 18109 else if ( type === 'columns' || type === 'rows' ) { 18110 // this has same length as context - one entry for each table 18111 ret = fn.call( apiInst, context[i], this[i], i ); 18112 18113 if ( ret !== undefined ) { 18114 a.push( ret ); 18115 } 18116 } 18117 else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) { 18118 // columns and rows share the same structure. 18119 // 'this' is an array of column indexes for each context 18120 items = this[i]; 18121 18122 if ( type === 'column-rows' ) { 18123 rows = _selector_row_indexes( context[i], selector.opts ); 18124 } 18125 18126 for ( j=0, jen=items.length ; j<jen ; j++ ) { 18127 item = items[j]; 18128 18129 if ( type === 'cell' ) { 18130 ret = fn.call( apiInst, context[i], item.row, item.column, i, j ); 18131 } 18132 else { 18133 ret = fn.call( apiInst, context[i], item, i, j, rows ); 18134 } 18135 18136 if ( ret !== undefined ) { 18137 a.push( ret ); 18138 } 18139 } 18140 } 18141 } 18142 18143 if ( a.length || alwaysNew ) { 18144 var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a ); 18145 var apiSelector = api.selector; 18146 apiSelector.rows = selector.rows; 18147 apiSelector.cols = selector.cols; 18148 apiSelector.opts = selector.opts; 18149 return api; 18150 } 18151 return this; 18152 }, 18153 18154 18155 lastIndexOf: __arrayProto.lastIndexOf || function (obj, start) 18156 { 18157 // Bit cheeky... 18158 return this.indexOf.apply( this.toArray.reverse(), arguments ); 18159 }, 18160 18161 18162 length: 0, 18163 18164 18165 map: function ( fn ) 18166 { 18167 var a = []; 18168 18169 if ( __arrayProto.map ) { 18170 a = __arrayProto.map.call( this, fn, this ); 18171 } 18172 else { 18173 // Compatibility for browsers without EMCA-252-5 (JS 1.6) 18174 for ( var i=0, ien=this.length ; i<ien ; i++ ) { 18175 a.push( fn.call( this, this[i], i ) ); 18176 } 18177 } 18178 18179 return new _Api( this.context, a ); 18180 }, 18181 18182 18183 pluck: function ( prop ) 18184 { 18185 return this.map( function ( el ) { 18186 return el[ prop ]
vendor: 28,402 bytes, lines 18186-19280
18186; 18187 } ); 18188 }, 18189 18190 pop: __arrayProto.pop, 18191 18192 18193 push: __arrayProto.push, 18194 18195 18196 // Does not return an API instance 18197 reduce: __arrayProto.reduce || function ( fn, init ) 18198 { 18199 return _fnReduce( this, fn, init, 0, this.length, 1 ); 18200 }, 18201 18202 18203 reduceRight: __arrayProto.reduceRight || function ( fn, init ) 18204 { 18205 return _fnReduce( this, fn, init, this.length-1, -1, -1 ); 18206 }, 18207 18208 18209 reverse: __arrayProto.reverse, 18210 18211 18212 // Object with rows, columns and opts 18213 selector: null, 18214 18215 18216 shift: __arrayProto.shift, 18217 18218 18219 slice: function () { 18220 return new _Api( this.context, this ); 18221 }, 18222 18223 18224 sort: __arrayProto.sort, // ? name - order? 18225 18226 18227 splice: __arrayProto.splice, 18228 18229 18230 toArray: function () 18231 { 18232 return __arrayProto.slice.call( this ); 18233 }, 18234 18235 18236 to$: function () 18237 { 18238 return $( this ); 18239 }, 18240 18241 18242 toJQuery: function () 18243 { 18244 return $( this ); 18245 }, 18246 18247 18248 unique: function () 18249 { 18250 return new _Api( this.context, _unique(this) ); 18251 }, 18252 18253 18254 unshift: __arrayProto.unshift 18255 } ); 18256 18257 18258 _Api.extend = function ( scope, obj, ext ) 18259 { 18260 // Only extend API instances and static properties of the API 18261 if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) { 18262 return; 18263 } 18264 18265 var 18266 i, ien, 18267 struct, 18268 methodScoping = function ( scope, fn, struc ) { 18269 return function () { 18270 var ret = fn.apply( scope, arguments ); 18271 18272 // Method extension 18273 _Api.extend( ret, ret, struc.methodExt ); 18274 return ret; 18275 }; 18276 }; 18277 18278 for ( i=0, ien=ext.length ; i<ien ; i++ ) { 18279 struct = ext[i]; 18280 18281 // Value 18282 obj[ struct.name ] = struct.type === 'function' ? 18283 methodScoping( scope, struct.val, struct ) : 18284 struct.type === 'object' ? 18285 {} : 18286 struct.val; 18287 18288 obj[ struct.name ].__dt_wrapper = true; 18289 18290 // Property extension 18291 _Api.extend( scope, obj[ struct.name ], struct.propExt ); 18292 } 18293 }; 18294 18295 18296 // @todo - Is there need for an augment function? 18297 // _Api.augment = function ( inst, name ) 18298 // { 18299 // // Find src object in the structure from the name 18300 // var parts = name.split('.'); 18301 18302 // _Api.extend( inst, obj ); 18303 // }; 18304 18305 18306 // [ 18307 // { 18308 // name: 'data' -- string - Property name 18309 // val: function () {}, -- function - Api method (or undefined if just an object 18310 // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result 18311 // propExt: [ ... ] -- array - Array of Api object definitions to extend the property 18312 // }, 18313 // { 18314 // name: 'row' 18315 // val: {}, 18316 // methodExt: [ ... ], 18317 // propExt: [ 18318 // { 18319 // name: 'data' 18320 // val: function () {}, 18321 // methodExt: [ ... ], 18322 // propExt: [ ... ] 18323 // }, 18324 // ... 18325 // ] 18326 // } 18327 // ] 18328 18329 _Api.register = _api_register = function ( name, val ) 18330 { 18331 if ( Array.isArray( name ) ) { 18332 for ( var j=0, jen=name.length ; j<jen ; j++ ) { 18333 _Api.register( name[j], val ); 18334 } 18335 return; 18336 } 18337 18338 var 18339 i, ien, 18340 heir = name.split('.'), 18341 struct = __apiStruct, 18342 key, method; 18343 18344 var find = function ( src, name ) { 18345 for ( var i=0, ien=src.length ; i<ien ; i++ ) { 18346 if ( src[i].name === name ) { 18347 return src[i]; 18348 } 18349 } 18350 return null; 18351 }; 18352 18353 for ( i=0, ien=heir.length ; i<ien ; i++ ) { 18354 method = heir[i].indexOf('()') !== -1; 18355 key = method ? 18356 heir[i].replace('()', '') : 18357 heir[i]; 18358 18359 var src = find( struct, key ); 18360 if ( ! src ) { 18361 src = { 18362 name: key, 18363 val: {}, 18364 methodExt: [], 18365 propExt: [], 18366 type: 'object' 18367 }; 18368 struct.push( src ); 18369 } 18370 18371 if ( i === ien-1 ) { 18372 src.val = val; 18373 src.type = typeof val === 'function' ? 18374 'function' : 18375 $.isPlainObject( val ) ? 18376 'object' : 18377 'other'; 18378 } 18379 else { 18380 struct = method ? 18381 src.methodExt : 18382 src.propExt; 18383 } 18384 } 18385 }; 18386 18387 _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) { 18388 _Api.register( pluralName, val ); 18389 18390 _Api.register( singularName, function () { 18391 var ret = val.apply( this, arguments ); 18392 18393 if ( ret === this ) { 18394 // Returned item is the API instance that was passed in, return it 18395 return this; 18396 } 18397 else if ( ret instanceof _Api ) { 18398 // New API instance returned, want the value from the first item 18399 // in the returned array for the singular result. 18400 return ret.length ? 18401 Array.isArray( ret[0] ) ? 18402 new _Api( ret.context, ret[0] ) : // Array results are 'enhanced' 18403 ret[0] : 18404 undefined; 18405 } 18406 18407 // Non-API return - just fire it back 18408 return ret; 18409 } ); 18410 }; 18411 18412 18413 /** 18414 * Selector for HTML tables. Apply the given selector to the give array of 18415 * DataTables settings objects. 18416 * 18417 * @param {string|integer} [selector] jQuery selector string or integer 18418 * @param {array} Array of DataTables settings objects to be filtered 18419 * @return {array} 18420 * @ignore 18421 */ 18422 var __table_selector = function ( selector, a ) 18423 { 18424 if ( Array.isArray(selector) ) { 18425 return $.map( selector, function (item) { 18426 return __table_selector(item, a); 18427 } ); 18428 } 18429 18430 // Integer is used to pick out a table by index 18431 if ( typeof selector === 'number' ) { 18432 return [ a[ selector ] ]; 18433 } 18434 18435 // Perform a jQuery selector on the table nodes 18436 var nodes = $.map( a, function (el, i) { 18437 return el.nTable; 18438 } ); 18439 18440 return $(nodes) 18441 .filter( selector ) 18442 .map( function (i) { 18443 // Need to translate back from the table node to the settings 18444 var idx = $.inArray( this, nodes ); 18445 return a[ idx ]; 18446 } ) 18447 .toArray(); 18448 }; 18449 18450 18451 18452 /** 18453 * Context selector for the API's context (i.e. the tables the API instance 18454 * refers to. 18455 * 18456 * @name DataTable.Api#tables 18457 * @param {string|integer} [selector] Selector to pick which tables the iterator 18458 * should operate on. If not given, all tables in the current context are 18459 * used. This can be given as a jQuery selector (for example `':gt(0)'`) to 18460 * select multiple tables or as an integer to select a single table. 18461 * @returns {DataTable.Api} Returns a new API instance if a selector is given. 18462 */ 18463 _api_register( 'tables()', function ( selector ) { 18464 // A new instance is created if there was a selector specified 18465 return selector !== undefined && selector !== null ? 18466 new _Api( __table_selector( selector, this.context ) ) : 18467 this; 18468 } ); 18469 18470 18471 _api_register( 'table()', function ( selector ) { 18472 var tables = this.tables( selector ); 18473 var ctx = tables.context; 18474 18475 // Truncate to the first matched table 18476 return ctx.length ? 18477 new _Api( ctx[0] ) : 18478 tables; 18479 } ); 18480 18481 18482 _api_registerPlural( 'tables().nodes()', 'table().node()' , function () { 18483 return this.iterator( 'table', function ( ctx ) { 18484 return ctx.nTable; 18485 }, 1 ); 18486 } ); 18487 18488 18489 _api_registerPlural( 'tables().body()', 'table().body()' , function () { 18490 return this.iterator( 'table', function ( ctx ) { 18491 return ctx.nTBody; 18492 }, 1 ); 18493 } ); 18494 18495 18496 _api_registerPlural( 'tables().header()', 'table().header()' , function () { 18497 return this.iterator( 'table', function ( ctx ) { 18498 return ctx.nTHead; 18499 }, 1 ); 18500 } ); 18501 18502 18503 _api_registerPlural( 'tables().footer()', 'table().footer()' , function () { 18504 return this.iterator( 'table', function ( ctx ) { 18505 return ctx.nTFoot; 18506 }, 1 ); 18507 } ); 18508 18509 18510 _api_registerPlural( 'tables().containers()', 'table().container()' , function () { 18511 return this.iterator( 'table', function ( ctx ) { 18512 return ctx.nTableWrapper; 18513 }, 1 ); 18514 } ); 18515 18516 18517 18518 /** 18519 * Redraw the tables in the current context. 18520 */ 18521 _api_register( 'draw()', function ( paging ) { 18522 return this.iterator( 'table', function ( settings ) { 18523 if ( paging === 'page' ) { 18524 _fnDraw( settings ); 18525 } 18526 else { 18527 if ( typeof paging === 'string' ) { 18528 paging = paging === 'full-hold' ? 18529 false : 18530 true; 18531 } 18532 18533 _fnReDraw( settings, paging===false ); 18534 } 18535 } ); 18536 } ); 18537 18538 18539 18540 /** 18541 * Get the current page index. 18542 * 18543 * @return {integer} Current page index (zero based) 18544 *//** 18545 * Set the current page. 18546 * 18547 * Note that if you attempt to show a page which does not exist, DataTables will 18548 * not throw an error, but rather reset the paging. 18549 * 18550 * @param {integer|string} action The paging action to take. This can be one of: 18551 * * `integer` - The page index to jump to 18552 * * `string` - An action to take: 18553 * * `first` - Jump to first page. 18554 * * `next` - Jump to the next page 18555 * * `previous` - Jump to previous page 18556 * * `last` - Jump to the last page. 18557 * @returns {DataTables.Api} this 18558 */ 18559 _api_register( 'page()', function ( action ) { 18560 if ( action === undefined ) { 18561 return this.page.info().page; // not an expensive call 18562 } 18563 18564 // else, have an action to take on all tables 18565 return this.iterator( 'table', function ( settings ) { 18566 _fnPageChange( settings, action ); 18567 } ); 18568 } ); 18569 18570 18571 /** 18572 * Paging information for the first table in the current context. 18573 * 18574 * If you require paging information for another table, use the `table()` method 18575 * with a suitable selector. 18576 * 18577 * @return {object} Object with the following properties set: 18578 * * `page` - Current page index (zero based - i.e. the first page is `0`) 18579 * * `pages` - Total number of pages 18580 * * `start` - Display index for the first record shown on the current page 18581 * * `end` - Display index for the last record shown on the current page 18582 * * `length` - Display length (number of records). Note that generally `start 18583 * + length = end`, but this is not always true, for example if there are 18584 * only 2 records to show on the final page, with a length of 10. 18585 * * `recordsTotal` - Full data set length 18586 * * `recordsDisplay` - Data set length once the current filtering criterion 18587 * are applied. 18588 */ 18589 _api_register( 'page.info()', function ( action ) { 18590 if ( this.context.length === 0 ) { 18591 return undefined; 18592 } 18593 18594 var 18595 settings = this.context[0], 18596 start = settings._iDisplayStart, 18597 len = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1, 18598 visRecords = settings.fnRecordsDisplay(), 18599 all = len === -1; 18600 18601 return { 18602 "page": all ? 0 : Math.floor( start / len ), 18603 "pages": all ? 1 : Math.ceil( visRecords / len ), 18604 "start": start, 18605 "end": settings.fnDisplayEnd(), 18606 "length": len, 18607 "recordsTotal": settings.fnRecordsTotal(), 18608 "recordsDisplay": visRecords, 18609 "serverSide": _fnDataSource( settings ) === 'ssp' 18610 }; 18611 } ); 18612 18613 18614 /** 18615 * Get the current page length. 18616 * 18617 * @return {integer} Current page length. Note `-1` indicates that all records 18618 * are to be shown. 18619 *//** 18620 * Set the current page length. 18621 * 18622 * @param {integer} Page length to set. Use `-1` to show all records. 18623 * @returns {DataTables.Api} this 18624 */ 18625 _api_register( 'page.len()', function ( len ) { 18626 // Note that we can't call this function 'length()' because `length` 18627 // is a Javascript property of functions which defines how many arguments 18628 // the function expects. 18629 if ( len === undefined ) { 18630 return this.context.length !== 0 ? 18631 this.context[0]._iDisplayLength : 18632 undefined; 18633 } 18634 18635 // else, set the page length 18636 return this.iterator( 'table', function ( settings ) { 18637 _fnLengthChange( settings, len ); 18638 } ); 18639 } ); 18640 18641 18642 18643 var __reload = function ( settings, holdPosition, callback ) { 18644 // Use the draw event to trigger a callback 18645 if ( callback ) { 18646 var api = new _Api( settings ); 18647 18648 api.one( 'draw', function () { 18649 callback( api.ajax.json() ); 18650 } ); 18651 } 18652 18653 if ( _fnDataSource( settings ) == 'ssp' ) { 18654 _fnReDraw( settings, holdPosition ); 18655 } 18656 else { 18657 _fnProcessingDisplay( settings, true ); 18658 18659 // Cancel an existing request 18660 var xhr = settings.jqXHR; 18661 if ( xhr && xhr.readyState !== 4 ) { 18662 xhr.abort(); 18663 } 18664 18665 // Trigger xhr 18666 _fnBuildAjax( settings, [], function( json ) { 18667 _fnClearTable( settings ); 18668 18669 var data = _fnAjaxDataSrc( settings, json ); 18670 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 18671 _fnAddData( settings, data[i] ); 18672 } 18673 18674 _fnReDraw( settings, holdPosition ); 18675 _fnProcessingDisplay( settings, false ); 18676 } ); 18677 } 18678 }; 18679 18680 18681 /** 18682 * Get the JSON response from the last Ajax request that DataTables made to the 18683 * server. Note that this returns the JSON from the first table in the current 18684 * context. 18685 * 18686 * @return {object} JSON received from the server. 18687 */ 18688 _api_register( 'ajax.json()', function () { 18689 var ctx = this.context; 18690 18691 if ( ctx.length > 0 ) { 18692 return ctx[0].json; 18693 } 18694 18695 // else return undefined; 18696 } ); 18697 18698 18699 /** 18700 * Get the data submitted in the last Ajax request 18701 */ 18702 _api_register( 'ajax.params()', function () { 18703 var ctx = this.context; 18704 18705 if ( ctx.length > 0 ) { 18706 return ctx[0].oAjaxData; 18707 } 18708 18709 // else return undefined; 18710 } ); 18711 18712 18713 /** 18714 * Reload tables from the Ajax data source. Note that this function will 18715 * automatically re-draw the table when the remote data has been loaded. 18716 * 18717 * @param {boolean} [reset=true] Reset (default) or hold the current paging 18718 * position. A full re-sort and re-filter is performed when this method is 18719 * called, which is why the pagination reset is the default action. 18720 * @returns {DataTables.Api} this 18721 */ 18722 _api_register( 'ajax.reload()', function ( callback, resetPaging ) { 18723 return this.iterator( 'table', function (settings) { 18724 __reload( settings, resetPaging===false, callback ); 18725 } ); 18726 } ); 18727 18728 18729 /** 18730 * Get the current Ajax URL. Note that this returns the URL from the first 18731 * table in the current context. 18732 * 18733 * @return {string} Current Ajax source URL 18734 *//** 18735 * Set the Ajax URL. Note that this will set the URL for all tables in the 18736 * current context. 18737 * 18738 * @param {string} url URL to set. 18739 * @returns {DataTables.Api} this 18740 */ 18741 _api_register( 'ajax.url()', function ( url ) { 18742 var ctx = this.context; 18743 18744 if ( url === undefined ) { 18745 // get 18746 if ( ctx.length === 0 ) { 18747 return undefined; 18748 } 18749 ctx = ctx[0]; 18750 18751 return ctx.ajax ? 18752 $.isPlainObject( ctx.ajax ) ? 18753 ctx.ajax.url : 18754 ctx.ajax : 18755 ctx.sAjaxSource; 18756 } 18757 18758 // set 18759 return this.iterator( 'table', function ( settings ) { 18760 if ( $.isPlainObject( settings.ajax ) ) { 18761 settings.ajax.url = url; 18762 } 18763 else { 18764 settings.ajax = url; 18765 } 18766 // No need to consider sAjaxSource here since DataTables gives priority 18767 // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any 18768 // value of `sAjaxSource` redundant. 18769 } ); 18770 } ); 18771 18772 18773 /** 18774 * Load data from the newly set Ajax URL. Note that this method is only 18775 * available when `ajax.url()` is used to set a URL. Additionally, this method 18776 * has the same effect as calling `ajax.reload()` but is provided for 18777 * convenience when setting a new URL. Like `ajax.reload()` it will 18778 * automatically redraw the table once the remote data has been loaded. 18779 * 18780 * @returns {DataTables.Api} this 18781 */ 18782 _api_register( 'ajax.url().load()', function ( callback, resetPaging ) { 18783 // Same as a reload, but makes sense to present it for easy access after a 18784 // url change 18785 return this.iterator( 'table', function ( ctx ) { 18786 __reload( ctx, resetPaging===false, callback ); 18787 } ); 18788 } ); 18789 18790 18791 18792 18793 var _selector_run = function ( type, selector, selectFn, settings, opts ) 18794 { 18795 var 18796 out = [], res, 18797 a, i, ien, j, jen, 18798 selectorType = typeof selector; 18799 18800 // Can't just check for isArray here, as an API or jQuery instance might be 18801 // given with their array like look 18802 if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) { 18803 selector = [ selector ]; 18804 } 18805 18806 for ( i=0, ien=selector.length ; i<ien ; i++ ) { 18807 // Only split on simple strings - complex expressions will be jQuery selectors 18808 a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ? 18809 selector[i].split(',') : 18810 [ selector[i] ]; 18811 18812 for ( j=0, jen=a.length ; j<jen ; j++ ) { 18813 res = selectFn( typeof a[j] === 'string' ? (a[j]).trim() : a[j] ); 18814 18815 if ( res && res.length ) { 18816 out = out.concat( res ); 18817 } 18818 } 18819 } 18820 18821 // selector extensions 18822 var ext = _ext.selector[ type ]; 18823 if ( ext.length ) { 18824 for ( i=0, ien=ext.length ; i<ien ; i++ ) { 18825 out = ext[i]( settings, opts, out ); 18826 } 18827 } 18828 18829 return _unique( out ); 18830 }; 18831 18832 18833 var _selector_opts = function ( opts ) 18834 { 18835 if ( ! opts ) { 18836 opts = {}; 18837 } 18838 18839 // Backwards compatibility for 1.9- which used the terminology filter rather 18840 // than search 18841 if ( opts.filter && opts.search === undefined ) { 18842 opts.search = opts.filter; 18843 } 18844 18845 return $.extend( { 18846 search: 'none', 18847 order: 'current', 18848 page: 'all' 18849 }, opts ); 18850 }; 18851 18852 18853 var _selector_first = function ( inst ) 18854 { 18855 // Reduce the API instance to the first item found 18856 for ( var i=0, ien=inst.length ; i<ien ; i++ ) { 18857 if ( inst[i].length > 0 ) { 18858 // Assign the first element to the first item in the instance 18859 // and truncate the instance and context 18860 inst[0] = inst[i]; 18861 inst[0].length = 1; 18862 inst.length = 1; 18863 inst.context = [ inst.context[i] ]; 18864 18865 return inst; 18866 } 18867 } 18868 18869 // Not found - return an empty instance 18870 inst.length = 0; 18871 return inst; 18872 }; 18873 18874 18875 var _selector_row_indexes = function ( settings, opts ) 18876 { 18877 var 18878 i, ien, tmp, a=[], 18879 displayFiltered = settings.aiDisplay, 18880 displayMaster = settings.aiDisplayMaster; 18881 18882 var 18883 search = opts.search, // none, applied, removed 18884 order = opts.order, // applied, current, index (original - compatibility with 1.9) 18885 page = opts.page; // all, current 18886 18887 if ( _fnDataSource( settings ) == 'ssp' ) { 18888 // In server-side processing mode, most options are irrelevant since 18889 // rows not shown don't exist and the index order is the applied order 18890 // Removed is a special case - for consistency just return an empty 18891 // array 18892 return search === 'removed' ? 18893 [] : 18894 _range( 0, displayMaster.length ); 18895 } 18896 else if ( page == 'current' ) { 18897 // Current page implies that order=current and filter=applied, since it is 18898 // fairly senseless otherwise, regardless of what order and search actually 18899 // are 18900 for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) { 18901 a.push( displayFiltered[i] ); 18902 } 18903 } 18904 else if ( order == 'current' || order == 'applied' ) { 18905 if ( search == 'none') { 18906 a = displayMaster.slice(); 18907 } 18908 else if ( search == 'applied' ) { 18909 a = displayFiltered.slice(); 18910 } 18911 else if ( search == 'removed' ) { 18912 // O(n+m) solution by creating a hash map 18913 var displayFilteredMap = {}; 18914 18915 for ( var i=0, ien=displayFiltered.length ; i<ien ; i++ ) { 18916 displayFilteredMap[displayFiltered[i]] = null; 18917 } 18918 18919 a = $.map( displayMaster, function (el) { 18920 return ! displayFilteredMap.hasOwnProperty(el) ? 18921 el : 18922 null; 18923 } ); 18924 } 18925 } 18926 else if ( order == 'index' || order == 'original' ) { 18927 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 18928 if ( search == 'none' ) { 18929 a.push( i ); 18930 } 18931 else { // applied | removed 18932 tmp = $.inArray( i, displayFiltered ); 18933 18934 if ((tmp === -1 && search == 'removed') || 18935 (tmp >= 0 && search == 'applied') ) 18936 { 18937 a.push( i ); 18938 } 18939 } 18940 } 18941 } 18942 18943 return a; 18944 }; 18945 18946 18947 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 18948 * Rows 18949 * 18950 * {} - no selector - use all available rows 18951 * {integer} - row aoData index 18952 * {node} - TR node 18953 * {string} - jQuery selector to apply to the TR elements 18954 * {array} - jQuery array of nodes, or simply an array of TR nodes 18955 * 18956 */ 18957 var __row_selector = function ( settings, selector, opts ) 18958 { 18959 var rows; 18960 var run = function ( sel ) { 18961 var selInt = _intVal( sel ); 18962 var i, ien; 18963 var aoData = settings.aoData; 18964 18965 // Short cut - selector is a number and no options provided (default is 18966 // all records, so no need to check if the index is in there, since it 18967 // must be - dev error if the index doesn't exist). 18968 if ( selInt !== null && ! opts ) { 18969 return [ selInt ]; 18970 } 18971 18972 if ( ! rows ) { 18973 rows = _selector_row_indexes( settings, opts ); 18974 } 18975 18976 if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) { 18977 // Selector - integer 18978 return [ selInt ]; 18979 } 18980 else if ( sel === null || sel === undefined || sel === '' ) { 18981 // Selector - none 18982 return rows; 18983 } 18984 18985 // Selector - function 18986 if ( typeof sel === 'function' ) { 18987 return $.map( rows, function (idx) { 18988 var row = aoData[ idx ]; 18989 return sel( idx, row._aData, row.nTr ) ? idx : null; 18990 } ); 18991 } 18992 18993 // Selector - node 18994 if ( sel.nodeName ) { 18995 var rowIdx = sel._DT_RowIndex; // Property added by DT for fast lookup 18996 var cellIdx = sel._DT_CellIndex; 18997 18998 if ( rowIdx !== undefined ) { 18999 // Make sure that the row is actually still present in the table 19000 return aoData[ rowIdx ] && aoData[ rowIdx ].nTr === sel ? 19001 [ rowIdx ] : 19002 []; 19003 } 19004 else if ( cellIdx ) { 19005 return aoData[ cellIdx.row ] && aoData[ cellIdx.row ].nTr === sel.parentNode ? 19006 [ cellIdx.row ] : 19007 []; 19008 } 19009 else { 19010 var host = $(sel).closest('*[data-dt-row]'); 19011 return host.length ? 19012 [ host.data('dt-row') ] : 19013 []; 19014 } 19015 } 19016 19017 // ID selector. Want to always be able to select rows by id, regardless 19018 // of if the tr element has been created or not, so can't rely upon 19019 // jQuery here - hence a custom implementation. This does not match 19020 // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything, 19021 // but to select it using a CSS selector engine (like Sizzle or 19022 // querySelect) it would need to need to be escaped for some characters. 19023 // DataTables simplifies this for row selectors since you can select 19024 // only a row. A # indicates an id any anything that follows is the id - 19025 // unescaped. 19026 if ( typeof sel === 'string' && sel.charAt(0) === '#' ) { 19027 // get row index from id 19028 var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ]; 19029 if ( rowObj !== undefined ) { 19030 return [ rowObj.idx ]; 19031 } 19032 19033 // need to fall through to jQuery in case there is DOM id that 19034 // matches 19035 } 19036 19037 // Get nodes in the order from the `rows` array with null values removed 19038 var nodes = _removeEmpty( 19039 _pluck_order( settings.aoData, rows, 'nTr' ) 19040 ); 19041 19042 // Selector - jQuery selector string, array of nodes or jQuery object/ 19043 // As jQuery's .filter() allows jQuery objects to be passed in filter, 19044 // it also allows arrays, so this will cope with all three options 19045 return $(nodes) 19046 .filter( sel ) 19047 .map( function () { 19048 return this._DT_RowIndex; 19049 } ) 19050 .toArray(); 19051 }; 19052 19053 return _selector_run( 'row', selector, run, settings, opts ); 19054 }; 19055 19056 19057 _api_register( 'rows()', function ( selector, opts ) { 19058 // argument shifting 19059 if ( selector === undefined ) { 19060 selector = ''; 19061 } 19062 else if ( $.isPlainObject( selector ) ) { 19063 opts = selector; 19064 selector = ''; 19065 } 19066 19067 opts = _selector_opts( opts ); 19068 19069 var inst = this.iterator( 'table', function ( settings ) { 19070 return __row_selector( settings, selector, opts ); 19071 }, 1 ); 19072 19073 // Want argument shifting here and in __row_selector? 19074 inst.selector.rows = selector; 19075 inst.selector.opts = opts; 19076 19077 return inst; 19078 } ); 19079 19080 _api_register( 'rows().nodes()', function () { 19081 return this.iterator( 'row', function ( settings, row ) { 19082 return settings.aoData[ row ].nTr || undefined; 19083 }, 1 ); 19084 } ); 19085 19086 _api_register( 'rows().data()', function () { 19087 return this.iterator( true, 'rows', function ( settings, rows ) { 19088 return _pluck_order( settings.aoData, rows, '_aData' ); 19089 }, 1 ); 19090 } ); 19091 19092 _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) { 19093 return this.iterator( 'row', function ( settings, row ) { 19094 var r = settings.aoData[ row ]; 19095 return type === 'search' ? r._aFilterData : r._aSortData; 19096 }, 1 ); 19097 } ); 19098 19099 _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) { 19100 return this.iterator( 'row', function ( settings, row ) { 19101 _fnInvalidate( settings, row, src ); 19102 } ); 19103 } ); 19104 19105 _api_registerPlural( 'rows().indexes()', 'row().index()', function () { 19106 return this.iterator( 'row', function ( settings, row ) { 19107 return row; 19108 }, 1 ); 19109 } ); 19110 19111 _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) { 19112 var a = []; 19113 var context = this.context; 19114 19115 // `iterator` will drop undefined values, but in this case we want them 19116 for ( var i=0, ien=context.length ; i<ien ; i++ ) { 19117 for ( var j=0, jen=this[i].length ; j<jen ; j++ ) { 19118 var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData ); 19119 a.push( (hash === true ? '#' : '' )+ id ); 19120 } 19121 } 19122 19123 return new _Api( context, a ); 19124 } ); 19125 19126 _api_registerPlural( 'rows().remove()', 'row().remove()', function () { 19127 var that = this; 19128 19129 this.iterator( 'row', function ( settings, row, thatIdx ) { 19130 var data = settings.aoData; 19131 var rowData = data[ row ]; 19132 var i, ien, j, jen; 19133 var loopRow, loopCells; 19134 19135 data.splice( row, 1 ); 19136 19137 // Update the cached indexes 19138 for ( i=0, ien=data.length ; i<ien ; i++ ) { 19139 loopRow = data[i]; 19140 loopCells = loopRow.anCells; 19141 19142 // Rows 19143 if ( loopRow.nTr !== null ) { 19144 loopRow.nTr._DT_RowIndex = i; 19145 } 19146 19147 // Cells 19148 if ( loopCells !== null ) { 19149 for ( j=0, jen=loopCells.length ; j<jen ; j++ ) { 19150 loopCells[j]._DT_CellIndex.row = i; 19151 } 19152 } 19153 } 19154 19155 // Delete from the display arrays 19156 _fnDeleteIndex( settings.aiDisplayMaster, row ); 19157 _fnDeleteIndex( settings.aiDisplay, row ); 19158 _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes 19159 19160 // For server-side processing tables - subtract the deleted row from the count 19161 if ( settings._iRecordsDisplay > 0 ) { 19162 settings._iRecordsDisplay--; 19163 } 19164 19165 // Check for an 'overflow' they case for displaying the table 19166 _fnLengthOverflow( settings ); 19167 19168 // Remove the row's ID reference if there is one 19169 var id = settings.rowIdFn( rowData._aData ); 19170 if ( id !== undefined ) { 19171 delete settings.aIds[ id ]; 19172 } 19173 } ); 19174 19175 this.iterator( 'table', function ( settings ) { 19176 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) { 19177 settings.aoData[i].idx = i; 19178 } 19179 } ); 19180 19181 return this; 19182 } ); 19183 19184 19185 _api_register( 'rows.add()', function ( rows ) { 19186 var newRows = this.iterator( 'table', function ( settings ) { 19187 var row, i, ien; 19188 var out = []; 19189 19190 for ( i=0, ien=rows.length ; i<ien ; i++ ) { 19191 row = rows[i]; 19192 19193 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) { 19194 out.push( _fnAddTr( settings, row )[0] ); 19195 } 19196 else { 19197 out.push( _fnAddData( settings, row ) ); 19198 } 19199 } 19200 19201 return out; 19202 }, 1 ); 19203 19204 // Return an Api.rows() extended instance, so rows().nodes() etc can be used 19205 var modRows = this.rows( -1 ); 19206 modRows.pop(); 19207 $.merge( modRows, newRows ); 19208 19209 return modRows; 19210 } ); 19211 19212 19213 19214 19215 19216 /** 19217 * 19218 */ 19219 _api_register( 'row()', function ( selector, opts ) { 19220 return _selector_first( this.rows( selector, opts ) ); 19221 } ); 19222 19223 19224 _api_register( 'row().data()', function ( data ) { 19225 var ctx = this.context; 19226 19227 if ( data === undefined ) { 19228 // Get 19229 return ctx.length && this.length ? 19230 ctx[0].aoData[ this[0] ]._aData : 19231 undefined; 19232 } 19233 19234 // Set 19235 var row = ctx[0].aoData[ this[0] ]; 19236 row._aData = data; 19237 19238 // If the DOM has an id, and the data source is an array 19239 if ( Array.isArray( data ) && row.nTr && row.nTr.id ) { 19240 _fnSetObjectDataFn( ctx[0].rowId )( data, row.nTr.id ); 19241 } 19242 19243 // Automatically invalidate 19244 _fnInvalidate( ctx[0], this[0], 'data' ); 19245 19246 return this; 19247 } ); 19248 19249 19250 _api_register( 'row().node()', function () { 19251 var ctx = this.context; 19252 19253 return ctx.length && this.length ? 19254 ctx[0].aoData[ this[0] ].nTr || null : 19255 null; 19256 } ); 19257 19258 19259 _api_register( 'row.add()', function ( row ) { 19260 // Allow a jQuery object to be passed in - only a single row is added from 19261 // it though - the first element in the set 19262 if ( row instanceof $ && row.length ) { 19263 row = row[0]; 19264 } 19265 19266 var rows = this.iterator( 'table', function ( settings ) { 19267 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) { 19268 return _fnAddTr( settings, row )[0]; 19269 } 19270 return _fnAddData( settings, row ); 19271 } ); 19272 19273 // Return an Api.rows() extended instance, with the newly added row selected 19274 return this.row( rows[0] ); 19275 } ); 19276 19277 19278 $(document).on('plugin-init.dt', function (e, context) { 19279 var api = new _Api( context ); 19280
19280api.on( 'stateSaveParams', function ( e, settings, data ) { 19281 var indexes = api.rows().iterator( 'row', function ( settings, idx ) { 19282 return settings.aoData[idx]._detailsShow ? idx : undefined; 19283 }); 19284 19285 data.childRows = api.rows( indexes ).ids( true ).toArray(); 19286 }) 19287 19288 var loaded = api.state.loaded(); 19289 19290 if ( loaded && loaded.childRows ) { 19291 api.rows( loaded.childRows ).every( function () { 19292 _fnCallbackFire( context, null, 'requestChild', [ this ] ) 19293 }) 19294 } 19295 }) 19296 19297 var __details_add = function ( ctx, row, data, klass ) 19298 { 19299 // Convert to array of TR elements 19300 var rows = []; 19301 var addRow = function ( r, k ) { 19302 // Recursion to allow for arrays of jQuery objects 19303 if ( Array.isArray( r ) || r instanceof $ ) { 19304 for ( var i=0, ien=r.length ; i<ien ; i++ ) { 19305 addRow( r[i], k ); 19306 } 19307 return; 19308 } 19309 19310 // If we get a TR element, then just add it directly - up to the dev 19311 // to add the correct number of columns etc 19312 if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) { 19313 rows.push( r ); 19314 } 19315 else { 19316 // Otherwise create a row with a wrapper 19317 var created = $('<tr><td></td></tr>').addClass( k ); 19318 $('td', created) 19319 .addClass( k ) 19320 .html( r ) 19321 [0].colSpan = _fnVisbleColumns( ctx ); 19322 19323 rows.push( created[0] ); 19324 } 19325 }; 19326 19327 addRow( data, klass ); 19328 19329 if ( row._details ) { 19330 row._details.detach(); 19331 } 19332 19333 row._details = $(rows); 19334 19335 // If the children were already shown, that state should be retained 19336 if ( row._detailsShow ) { 19337 row._details.insertAfter( row.nTr ); 19338 } 19339 }; 19340 19341 19342 var __details_remove = function ( api, idx ) 19343 { 19344 var ctx = api.context; 19345 19346 if ( ctx.length ) { 19347 var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ]; 19348 19349 if ( row && row._details ) { 19350 row._details.remove(); 19351 19352 row._detailsShow = undefined; 19353 row._details = undefined; 19354 $( row.nTr ).removeClass( 'dt-hasChild' ); 19355 _fnSaveState( ctx[0] ); 19356 } 19357 } 19358 }; 19359 19360 19361 var __details_display = function ( api, show ) { 19362 var ctx = api.context; 19363 19364 if ( ctx.length && api.length ) { 19365 var row = ctx[0].aoData[ api[0] ]; 19366 19367 if ( row._details ) { 19368 row._detailsShow = show; 19369 19370 if ( show ) { 19371 row._details.insertAfter( row.nTr ); 19372 $( row.nTr ).addClass( 'dt-hasChild' ); 19373 } 19374 else { 19375 row._details.detach(); 19376 $( row.nTr ).removeClass( 'dt-hasChild' ); 19377 } 19378 19379 _fnCallbackFire( ctx[0], null, 'childRow', [ show, api.row( api[0] ) ] ) 19380 19381 __details_events( ctx[0] ); 19382 _fnSaveState( ctx[0] ); 19383 } 19384 } 19385 }; 19386 19387 19388 var __details_events = function ( settings ) 19389 { 19390 var api = new _Api( settings ); 19391 var namespace = '.dt.DT_details'; 19392 var drawEvent = 'draw'+namespace; 19393 var colvisEvent = 'column-visibility
vendor: 22,869 bytes, lines 19393-20254
19393'+namespace; 19394 var destroyEvent = 'destroy'+namespace; 19395 var data = settings.aoData; 19396 19397 api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent ); 19398 19399 if ( _pluck( data, '_details' ).length > 0 ) { 19400 // On each draw, insert the required elements into the document 19401 api.on( drawEvent, function ( e, ctx ) { 19402 if ( settings !== ctx ) { 19403 return; 19404 } 19405 19406 api.rows( {page:'current'} ).eq(0).each( function (idx) { 19407 // Internal data grab 19408 var row = data[ idx ]; 19409 19410 if ( row._detailsShow ) { 19411 row._details.insertAfter( row.nTr ); 19412 } 19413 } ); 19414 } ); 19415 19416 // Column visibility change - update the colspan 19417 api.on( colvisEvent, function ( e, ctx, idx, vis ) { 19418 if ( settings !== ctx ) { 19419 return; 19420 } 19421 19422 // Update the colspan for the details rows (note, only if it already has 19423 // a colspan) 19424 var row, visible = _fnVisbleColumns( ctx ); 19425 19426 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 19427 row = data[i]; 19428 19429 if ( row._details ) { 19430 row._details.children('td[colspan]').attr('colspan', visible ); 19431 } 19432 } 19433 } ); 19434 19435 // Table destroyed - nuke any child rows 19436 api.on( destroyEvent, function ( e, ctx ) { 19437 if ( settings !== ctx ) { 19438 return; 19439 } 19440 19441 for ( var i=0, ien=data.length ; i<ien ; i++ ) { 19442 if ( data[i]._details ) { 19443 __details_remove( api, i ); 19444 } 19445 } 19446 } ); 19447 } 19448 }; 19449 19450 // Strings for the method names to help minification 19451 var _emp = ''; 19452 var _child_obj = _emp+'row().child'; 19453 var _child_mth = _child_obj+'()'; 19454 19455 // data can be: 19456 // tr 19457 // string 19458 // jQuery or array of any of the above 19459 _api_register( _child_mth, function ( data, klass ) { 19460 var ctx = this.context; 19461 19462 if ( data === undefined ) { 19463 // get 19464 return ctx.length && this.length ? 19465 ctx[0].aoData[ this[0] ]._details : 19466 undefined; 19467 } 19468 else if ( data === true ) { 19469 // show 19470 this.child.show(); 19471 } 19472 else if ( data === false ) { 19473 // remove 19474 __details_remove( this ); 19475 } 19476 else if ( ctx.length && this.length ) { 19477 // set 19478 __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass ); 19479 } 19480 19481 return this; 19482 } ); 19483 19484 19485 _api_register( [ 19486 _child_obj+'.show()', 19487 _child_mth+'.show()' // only when `child()` was called with parameters (without 19488 ], function ( show ) { // it returns an object and this method is not executed) 19489 __details_display( this, true ); 19490 return this; 19491 } ); 19492 19493 19494 _api_register( [ 19495 _child_obj+'.hide()', 19496 _child_mth+'.hide()' // only when `child()` was called with parameters (without 19497 ], function () { // it returns an object and this method is not executed) 19498 __details_display( this, false ); 19499 return this; 19500 } ); 19501 19502 19503 _api_register( [ 19504 _child_obj+'.remove()', 19505 _child_mth+'.remove()' // only when `child()` was called with parameters (without 19506 ], function () { // it returns an object and this method is not executed) 19507 __details_remove( this ); 19508 return this; 19509 } ); 19510 19511 19512 _api_register( _child_obj+'.isShown()', function () { 19513 var ctx = this.context; 19514 19515 if ( ctx.length && this.length ) { 19516 // _detailsShown as false or undefined will fall through to return false 19517 return ctx[0].aoData[ this[0] ]._detailsShow || false; 19518 } 19519 return false; 19520 } ); 19521 19522 19523 19524 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 19525 * Columns 19526 * 19527 * {integer} - column index (>=0 count from left, <0 count from right) 19528 * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right) 19529 * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right) 19530 * "{string}:name" - column name 19531 * "{string}" - jQuery selector on column header nodes 19532 * 19533 */ 19534 19535 // can be an array of these items, comma separated list, or an array of comma 19536 // separated lists 19537 19538 var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/; 19539 19540 19541 // r1 and r2 are redundant - but it means that the parameters match for the 19542 // iterator callback in columns().data() 19543 var __columnData = function ( settings, column, r1, r2, rows ) { 19544 var a = []; 19545 for ( var row=0, ien=rows.length ; row<ien ; row++ ) { 19546 a.push( _fnGetCellData( settings, rows[row], column ) ); 19547 } 19548 return a; 19549 }; 19550 19551 19552 var __column_selector = function ( settings, selector, opts ) 19553 { 19554 var 19555 columns = settings.aoColumns, 19556 names = _pluck( columns, 'sName' ), 19557 nodes = _pluck( columns, 'nTh' ); 19558 19559 var run = function ( s ) { 19560 var selInt = _intVal( s ); 19561 19562 // Selector - all 19563 if ( s === '' ) { 19564 return _range( columns.length ); 19565 } 19566 19567 // Selector - index 19568 if ( selInt !== null ) { 19569 return [ selInt >= 0 ? 19570 selInt : // Count from left 19571 columns.length + selInt // Count from right (+ because its a negative value) 19572 ]; 19573 } 19574 19575 // Selector = function 19576 if ( typeof s === 'function' ) { 19577 var rows = _selector_row_indexes( settings, opts ); 19578 19579 return $.map( columns, function (col, idx) { 19580 return s( 19581 idx, 19582 __columnData( settings, idx, 0, 0, rows ), 19583 nodes[ idx ] 19584 ) ? idx : null; 19585 } ); 19586 } 19587 19588 // jQuery or string selector 19589 var match = typeof s === 'string' ? 19590 s.match( __re_column_selector ) : 19591 ''; 19592 19593 if ( match ) { 19594 switch( match[2] ) { 19595 case 'visIdx': 19596 case 'visible': 19597 var idx = parseInt( match[1], 10 ); 19598 // Visible index given, convert to column index 19599 if ( idx < 0 ) { 19600 // Counting from the right 19601 var visColumns = $.map( columns, function (col,i) { 19602 return col.bVisible ? i : null; 19603 } ); 19604 return [ visColumns[ visColumns.length + idx ] ]; 19605 } 19606 // Counting from the left 19607 return [ _fnVisibleToColumnIndex( settings, idx ) ]; 19608 19609 case 'name': 19610 // match by name. `names` is column index complete and in order 19611 return $.map( names, function (name, i) { 19612 return name === match[1] ? i : null; 19613 } ); 19614 19615 default: 19616 return []; 19617 } 19618 } 19619 19620 // Cell in the table body 19621 if ( s.nodeName && s._DT_CellIndex ) { 19622 return [ s._DT_CellIndex.column ]; 19623 } 19624 19625 // jQuery selector on the TH elements for the columns 19626 var jqResult = $( nodes ) 19627 .filter( s ) 19628 .map( function () { 19629 return $.inArray( this, nodes ); // `nodes` is column index complete and in order 19630 } ) 19631 .toArray(); 19632 19633 if ( jqResult.length || ! s.nodeName ) { 19634 return jqResult; 19635 } 19636 19637 // Otherwise a node which might have a `dt-column` data attribute, or be 19638 // a child or such an element 19639 var host = $(s).closest('*[data-dt-column]'); 19640 return host.length ? 19641 [ host.data('dt-column') ] : 19642 []; 19643 }; 19644 19645 return _selector_run( 'column', selector, run, settings, opts ); 19646 }; 19647 19648 19649 var __setColumnVis = function ( settings, column, vis ) { 19650 var 19651 cols = settings.aoColumns, 19652 col = cols[ column ], 19653 data = settings.aoData, 19654 row, cells, i, ien, tr; 19655 19656 // Get 19657 if ( vis === undefined ) { 19658 return col.bVisible; 19659 } 19660 19661 // Set 19662 // No change 19663 if ( col.bVisible === vis ) { 19664 return; 19665 } 19666 19667 if ( vis ) { 19668 // Insert column 19669 // Need to decide if we should use appendChild or insertBefore 19670 var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 ); 19671 19672 for ( i=0, ien=data.length ; i<ien ; i++ ) { 19673 tr = data[i].nTr; 19674 cells = data[i].anCells; 19675 19676 if ( tr ) { 19677 // insertBefore can act like appendChild if 2nd arg is null 19678 tr.insertBefore( cells[ column ], cells[ insertBefore ] || null ); 19679 } 19680 } 19681 } 19682 else { 19683 // Remove column 19684 $( _pluck( settings.aoData, 'anCells', column ) ).detach(); 19685 } 19686 19687 // Common actions 19688 col.bVisible = vis; 19689 }; 19690 19691 19692 _api_register( 'columns()', function ( selector, opts ) { 19693 // argument shifting 19694 if ( selector === undefined ) { 19695 selector = ''; 19696 } 19697 else if ( $.isPlainObject( selector ) ) { 19698 opts = selector; 19699 selector = ''; 19700 } 19701 19702 opts = _selector_opts( opts ); 19703 19704 var inst = this.iterator( 'table', function ( settings ) { 19705 return __column_selector( settings, selector, opts ); 19706 }, 1 ); 19707 19708 // Want argument shifting here and in _row_selector? 19709 inst.selector.cols = selector; 19710 inst.selector.opts = opts; 19711 19712 return inst; 19713 } ); 19714 19715 _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) { 19716 return this.iterator( 'column', function ( settings, column ) { 19717 return settings.aoColumns[column].nTh; 19718 }, 1 ); 19719 } ); 19720 19721 _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) { 19722 return this.iterator( 'column', function ( settings, column ) { 19723 return settings.aoColumns[column].nTf; 19724 }, 1 ); 19725 } ); 19726 19727 _api_registerPlural( 'columns().data()', 'column().data()', function () { 19728 return this.iterator( 'column-rows', __columnData, 1 ); 19729 } ); 19730 19731 _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () { 19732 return this.iterator( 'column', function ( settings, column ) { 19733 return settings.aoColumns[column].mData; 19734 }, 1 ); 19735 } ); 19736 19737 _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) { 19738 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) { 19739 return _pluck_order( settings.aoData, rows, 19740 type === 'search' ? '_aFilterData' : '_aSortData', column 19741 ); 19742 }, 1 ); 19743 } ); 19744 19745 _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () { 19746 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) { 19747 return _pluck_order( settings.aoData, rows, 'anCells', column ) ; 19748 }, 1 ); 19749 } ); 19750 19751 _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) { 19752 var that = this; 19753 var ret = this.iterator( 'column', function ( settings, column ) { 19754 if ( vis === undefined ) { 19755 return settings.aoColumns[ column ].bVisible; 19756 } // else 19757 __setColumnVis( settings, column, vis ); 19758 } ); 19759 19760 // Group the column visibility changes 19761 if ( vis !== undefined ) { 19762 this.iterator( 'table', function ( settings ) { 19763 // Redraw the header after changes 19764 _fnDrawHead( settings, settings.aoHeader ); 19765 _fnDrawHead( settings, settings.aoFooter ); 19766 19767 // Update colspan for no records display. Child rows and extensions will use their own 19768 // listeners to do this - only need to update the empty table item here 19769 if ( ! settings.aiDisplay.length ) { 19770 $(settings.nTBody).find('td[colspan]').attr('colspan', _fnVisbleColumns(settings)); 19771 } 19772 19773 _fnSaveState( settings ); 19774 19775 // Second loop once the first is done for events 19776 that.iterator( 'column', function ( settings, column ) { 19777 _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] ); 19778 } ); 19779 19780 if ( calc === undefined || calc ) { 19781 that.columns.adjust(); 19782 } 19783 }); 19784 } 19785 19786 return ret; 19787 } ); 19788 19789 _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) { 19790 return this.iterator( 'column', function ( settings, column ) { 19791 return type === 'visible' ? 19792 _fnColumnIndexToVisible( settings, column ) : 19793 column; 19794 }, 1 ); 19795 } ); 19796 19797 _api_register( 'columns.adjust()', function () { 19798 return this.iterator( 'table', function ( settings ) { 19799 _fnAdjustColumnSizing( settings ); 19800 }, 1 ); 19801 } ); 19802 19803 _api_register( 'column.index()', function ( type, idx ) { 19804 if ( this.context.length !== 0 ) { 19805 var ctx = this.context[0]; 19806 19807 if ( type === 'fromVisible' || type === 'toData' ) { 19808 return _fnVisibleToColumnIndex( ctx, idx ); 19809 } 19810 else if ( type === 'fromData' || type === 'toVisible' ) { 19811 return _fnColumnIndexToVisible( ctx, idx ); 19812 } 19813 } 19814 } ); 19815 19816 _api_register( 'column()', function ( selector, opts ) { 19817 return _selector_first( this.columns( selector, opts ) ); 19818 } ); 19819 19820 var __cell_selector = function ( settings, selector, opts ) 19821 { 19822 var data = settings.aoData; 19823 var rows = _selector_row_indexes( settings, opts ); 19824 var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) ); 19825 var allCells = $(_flatten( [], cells )); 19826 var row; 19827 var columns = settings.aoColumns.length; 19828 var a, i, ien, j, o, host; 19829 19830 var run = function ( s ) { 19831 var fnSelector = typeof s === 'function'; 19832 19833 if ( s === null || s === undefined || fnSelector ) { 19834 // All cells and function selectors 19835 a = []; 19836 19837 for ( i=0, ien=rows.length ; i<ien ; i++ ) { 19838 row = rows[i]; 19839 19840 for ( j=0 ; j<columns ; j++ ) { 19841 o = { 19842 row: row, 19843 column: j 19844 }; 19845 19846 if ( fnSelector ) { 19847 // Selector - function 19848 host = data[ row ]; 19849 19850 if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) { 19851 a.push( o ); 19852 } 19853 } 19854 else { 19855 // Selector - all 19856 a.push( o ); 19857 } 19858 } 19859 } 19860 19861 return a; 19862 } 19863 19864 // Selector - index 19865 if ( $.isPlainObject( s ) ) { 19866 // Valid cell index and its in the array of selectable rows 19867 return s.column !== undefined && s.row !== undefined && $.inArray( s.row, rows ) !== -1 ? 19868 [s] : 19869 []; 19870 } 19871 19872 // Selector - jQuery filtered cells 19873 var jqResult = allCells 19874 .filter( s ) 19875 .map( function (i, el) { 19876 return { // use a new object, in case someone changes the values 19877 row: el._DT_CellIndex.row, 19878 column: el._DT_CellIndex.column 19879 }; 19880 } ) 19881 .toArray(); 19882 19883 if ( jqResult.length || ! s.nodeName ) { 19884 return jqResult; 19885 } 19886 19887 // Otherwise the selector is a node, and there is one last option - the 19888 // element might be a child of an element which has dt-row and dt-column 19889 // data attributes 19890 host = $(s).closest('*[data-dt-row]'); 19891 return host.length ? 19892 [ { 19893 row: host.data('dt-row'), 19894 column: host.data('dt-column') 19895 } ] : 19896 []; 19897 }; 19898 19899 return _selector_run( 'cell', selector, run, settings, opts ); 19900 }; 19901 19902 19903 19904 19905 _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) { 19906 // Argument shifting 19907 if ( $.isPlainObject( rowSelector ) ) { 19908 // Indexes 19909 if ( rowSelector.row === undefined ) { 19910 // Selector options in first parameter 19911 opts = rowSelector; 19912 rowSelector = null; 19913 } 19914 else { 19915 // Cell index objects in first parameter 19916 opts = columnSelector; 19917 columnSelector = null; 19918 } 19919 } 19920 if ( $.isPlainObject( columnSelector ) ) { 19921 opts = columnSelector; 19922 columnSelector = null; 19923 } 19924 19925 // Cell selector 19926 if ( columnSelector === null || columnSelector === undefined ) { 19927 return this.iterator( 'table', function ( settings ) { 19928 return __cell_selector( settings, rowSelector, _selector_opts( opts ) ); 19929 } ); 19930 } 19931 19932 // The default built in options need to apply to row and columns 19933 var internalOpts = opts ? { 19934 page: opts.page, 19935 order: opts.order, 19936 search: opts.search 19937 } : {}; 19938 19939 // Row + column selector 19940 var columns = this.columns( columnSelector, internalOpts ); 19941 var rows = this.rows( rowSelector, internalOpts ); 19942 var i, ien, j, jen; 19943 19944 var cellsNoOpts = this.iterator( 'table', function ( settings, idx ) { 19945 var a = []; 19946 19947 for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) { 19948 for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) { 19949 a.push( { 19950 row: rows[idx][i], 19951 column: columns[idx][j] 19952 } ); 19953 } 19954 } 19955 19956 return a; 19957 }, 1 ); 19958 19959 // There is currently only one extension which uses a cell selector extension 19960 // It is a _major_ performance drag to run this if it isn't needed, so this is 19961 // an extension specific check at the moment 19962 var cells = opts && opts.selected ? 19963 this.cells( cellsNoOpts, opts ) : 19964 cellsNoOpts; 19965 19966 $.extend( cells.selector, { 19967 cols: columnSelector, 19968 rows: rowSelector, 19969 opts: opts 19970 } ); 19971 19972 return cells; 19973 } ); 19974 19975 19976 _api_registerPlural( 'cells().nodes()', 'cell().node()', function () { 19977 return this.iterator( 'cell', function ( settings, row, column ) { 19978 var data = settings.aoData[ row ]; 19979 19980 return data && data.anCells ? 19981 data.anCells[ column ] : 19982 undefined; 19983 }, 1 ); 19984 } ); 19985 19986 19987 _api_register( 'cells().data()', function () { 19988 return this.iterator( 'cell', function ( settings, row, column ) { 19989 return _fnGetCellData( settings, row, column ); 19990 }, 1 ); 19991 } ); 19992 19993 19994 _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) { 19995 type = type === 'search' ? '_aFilterData' : '_aSortData'; 19996 19997 return this.iterator( 'cell', function ( settings, row, column ) { 19998 return settings.aoData[ row ][ type ][ column ]; 19999 }, 1 ); 20000 } ); 20001 20002 20003 _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) { 20004 return this.iterator( 'cell', function ( settings, row, column ) { 20005 return _fnGetCellData( settings, row, column, type ); 20006 }, 1 ); 20007 } ); 20008 20009 20010 _api_registerPlural( 'cells().indexes()', 'cell().index()', function () { 20011 return this.iterator( 'cell', function ( settings, row, column ) { 20012 return { 20013 row: row, 20014 column: column, 20015 columnVisible: _fnColumnIndexToVisible( settings, column ) 20016 }; 20017 }, 1 ); 20018 } ); 20019 20020 20021 _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) { 20022 return this.iterator( 'cell', function ( settings, row, column ) { 20023 _fnInvalidate( settings, row, src, column ); 20024 } ); 20025 } ); 20026 20027 20028 20029 _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) { 20030 return _selector_first( this.cells( rowSelector, columnSelector, opts ) ); 20031 } ); 20032 20033 20034 _api_register( 'cell().data()', function ( data ) { 20035 var ctx = this.context; 20036 var cell = this[0]; 20037 20038 if ( data === undefined ) { 20039 // Get 20040 return ctx.length && cell.length ? 20041 _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) : 20042 undefined; 20043 } 20044 20045 // Set 20046 _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data ); 20047 _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column ); 20048 20049 return this; 20050 } ); 20051 20052 20053 20054 /** 20055 * Get current ordering (sorting) that has been applied to the table. 20056 * 20057 * @returns {array} 2D array containing the sorting information for the first 20058 * table in the current context. Each element in the parent array represents 20059 * a column being sorted upon (i.e. multi-sorting with two columns would have 20060 * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is 20061 * the column index that the sorting condition applies to, the second is the 20062 * direction of the sort (`desc` or `asc`) and, optionally, the third is the 20063 * index of the sorting order from the `column.sorting` initialisation array. 20064 *//** 20065 * Set the ordering for the table. 20066 * 20067 * @param {integer} order Column index to sort upon. 20068 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`) 20069 * @returns {DataTables.Api} this 20070 *//** 20071 * Set the ordering for the table. 20072 * 20073 * @param {array} order 1D array of sorting information to be applied. 20074 * @param {array} [...] Optional additional sorting conditions 20075 * @returns {DataTables.Api} this 20076 *//** 20077 * Set the ordering for the table. 20078 * 20079 * @param {array} order 2D array of sorting information to be applied. 20080 * @returns {DataTables.Api} this 20081 */ 20082 _api_register( 'order()', function ( order, dir ) { 20083 var ctx = this.context; 20084 20085 if ( order === undefined ) { 20086 // get 20087 return ctx.length !== 0 ? 20088 ctx[0].aaSorting : 20089 undefined; 20090 } 20091 20092 // set 20093 if ( typeof order === 'number' ) { 20094 // Simple column / direction passed in 20095 order = [ [ order, dir ] ]; 20096 } 20097 else if ( order.length && ! Array.isArray( order[0] ) ) { 20098 // Arguments passed in (list of 1D arrays) 20099 order = Array.prototype.slice.call( arguments ); 20100 } 20101 // otherwise a 2D array was passed in 20102 20103 return this.iterator( 'table', function ( settings ) { 20104 settings.aaSorting = order.slice(); 20105 } ); 20106 } ); 20107 20108 20109 /** 20110 * Attach a sort listener to an element for a given column 20111 * 20112 * @param {node|jQuery|string} node Identifier for the element(s) to attach the 20113 * listener to. This can take the form of a single DOM node, a jQuery 20114 * collection of nodes or a jQuery selector which will identify the node(s). 20115 * @param {integer} column the column that a click on this node will sort on 20116 * @param {function} [callback] callback function when sort is run 20117 * @returns {DataTables.Api} this 20118 */ 20119 _api_register( 'order.listener()', function ( node, column, callback ) { 20120 return this.iterator( 'table', function ( settings ) { 20121 _fnSortAttachListener( settings, node, column, callback ); 20122 } ); 20123 } ); 20124 20125 20126 _api_register( 'order.fixed()', function ( set ) { 20127 if ( ! set ) { 20128 var ctx = this.context; 20129 var fixed = ctx.length ? 20130 ctx[0].aaSortingFixed : 20131 undefined; 20132 20133 return Array.isArray( fixed ) ? 20134 { pre: fixed } : 20135 fixed; 20136 } 20137 20138 return this.iterator( 'table', function ( settings ) { 20139 settings.aaSortingFixed = $.extend( true, {}, set ); 20140 } ); 20141 } ); 20142 20143 20144 // Order by the selected column(s) 20145 _api_register( [ 20146 'columns().order()', 20147 'column().order()' 20148 ], function ( dir ) { 20149 var that = this; 20150 20151 return this.iterator( 'table', function ( settings, i ) { 20152 var sort = []; 20153 20154 $.each( that[i], function (j, col) { 20155 sort.push( [ col, dir ] ); 20156 } ); 20157 20158 settings.aaSorting = sort; 20159 } ); 20160 } ); 20161 20162 20163 20164 _api_register( 'search()', function ( input, regex, smart, caseInsen ) { 20165 var ctx = this.context; 20166 20167 if ( input === undefined ) { 20168 // get 20169 return ctx.length !== 0 ? 20170 ctx[0].oPreviousSearch.sSearch : 20171 undefined; 20172 } 20173 20174 // set 20175 return this.iterator( 'table', function ( settings ) { 20176 if ( ! settings.oFeatures.bFilter ) { 20177 return; 20178 } 20179 20180 _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, { 20181 "sSearch": input+"", 20182 "bRegex": regex === null ? false : regex, 20183 "bSmart": smart === null ? true : smart, 20184 "bCaseInsensitive": caseInsen === null ? true : caseInsen 20185 } ), 1 ); 20186 } ); 20187 } ); 20188 20189 20190 _api_registerPlural( 20191 'columns().search()', 20192 'column().search()', 20193 function ( input, regex, smart, caseInsen ) { 20194 return this.iterator( 'column', function ( settings, column ) { 20195 var preSearch = settings.aoPreSearchCols; 20196 20197 if ( input === undefined ) { 20198 // get 20199 return preSearch[ column ].sSearch; 20200 } 20201 20202 // set 20203 if ( ! settings.oFeatures.bFilter ) { 20204 return; 20205 } 20206 20207 $.extend( preSearch[ column ], { 20208 "sSearch": input+"", 20209 "bRegex": regex === null ? false : regex, 20210 "bSmart": smart === null ? true : smart, 20211 "bCaseInsensitive": caseInsen === null ? true : caseInsen 20212 } ); 20213 20214 _fnFilterComplete( settings, settings.oPreviousSearch, 1 ); 20215 } ); 20216 } 20217 ); 20218 20219 /* 20220 * State API methods 20221 */ 20222 20223 _api_register( 'state()', function () { 20224 return this.context.length ? 20225 this.context[0].oSavedState : 20226 null; 20227 } ); 20228 20229 20230 _api_register( 'state.clear()', function () { 20231 return this.iterator( 'table', function ( settings ) { 20232 // Save an empty object 20233 settings.fnStateSaveCallback.call( settings.oInstance, settings, {} ); 20234 } ); 20235 } ); 20236 20237 20238 _api_register( 'state.loaded()', function () { 20239 return this.context.length ? 20240 this.context[0].oLoadedState : 20241 null; 20242 } ); 20243 20244 20245 _api_register( 'state.save()', function () { 20246 return this.iterator( 'table', function ( settings ) { 20247 _fnSaveState( settings ); 20248 } ); 20249 } ); 20250 20251 20252 20253 /** 20254 *
20254Provide a common method for plug-ins to check the version of DataTables being 20255 * used, in order to ensure compatibility. 20256 * 20257 * @param {string} version Version string to check for, in the format "X.Y.Z". 20258 * Note that the formats "X" and "X.Y" are also acceptable. 20259 * @returns {boolean} true if this version of DataTables is greater or equal to 20260 * the required version, or false if this version of DataTales is not 20261 * suitable 20262 * @static 20263 * @dtopt API-Static 20264 * 20265 * @example 20266 * alert( $.fn.dataTable.versionCheck( '1.9.0' ) ); 20267 */ 20268 DataTable.versionCheck = DataTable.fnVersionCheck = function( version ) 20269 { 20270 var aThis = DataTable.version.split('.'); 20271 var aThat = version.split('.'); 20272 var iThis, iThat; 20273 20274 for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) { 20275 iThis = parseInt( aThis[i], 10 ) || 0; 20276 iThat = parseInt( aThat[i], 10 ) || 0; 20277 20278 // Parts are the same, keep comparing 20279 if (iThis === iThat) { 20280 continue; 20281 } 20282 20283 // Parts are different, return immediately 20284 return iThis > iThat; 20285 } 20286 20287 return true; 20288 }; 20289 20290 20291 /** 20292 * Check if a `<table>` node is a DataTable table already or not. 20293 * 20294 * @param {node|jquery|string} table Table node, jQuery object or jQuery 20295 * selector for the table to test. Note that if more than more than one 20296 * table is passed on, only the first will be checked 20297 * @returns {boolean} true the table given is a DataTable, or false otherwise 20298 * @static 20299 * @dtopt API-Static 20300 * 20301 * @example 20302 * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) { 20303 * $('#example').dataTable(); 20304 * } 20305 */ 20306 DataTable.isDataTable = DataTable.fnIsDataTable = function ( table ) 20307 { 20308 var t = $(table).get(0); 20309 var is = false; 20310 20311 if ( table instanceof DataTable.Api ) { 20312 return true; 20313 } 20314 20315 $.each( DataTable.settings, function (i, o) { 20316 var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null; 20317 var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null; 20318 20319 if ( o.nTable === t || head === t || foot === t ) { 20320 is = true; 20321 } 20322 } ); 20323 20324 return is; 20325 }; 20326 20327 20328 /** 20329 * Get all DataTable tables that have been initialised - optionally you can 20330 * select to get only currently visible tables. 20331 * 20332 * @param {boolean} [visible=false] Flag to indicate if you want all (default) 20333 * or visible tables only. 20334 * @returns {array} Array of `table` nodes (not DataTable instances) which are 20335 * DataTables 20336 * @static 20337 * @dtopt API-Static 20338 * 20339 * @example 20340 * $.each( $.fn.dataTable.tables(true), function () { 20341 * $(table).DataTable().columns.adjust(); 20342 * } ); 20343 */ 20344 DataTable.tables = DataTable.fnTables = function ( visible ) 20345 { 20346 var api = false;
vendor: 7,568 bytes, lines 20347-20607
20347 20348 if ( $.isPlainObject( visible ) ) { 20349 api = visible.api; 20350 visible = visible.visible; 20351 } 20352 20353 var a = $.map( DataTable.settings, function (o) { 20354 if ( !visible || (visible && $(o.nTable).is(':visible')) ) { 20355 return o.nTable; 20356 } 20357 } ); 20358 20359 return api ? 20360 new _Api( a ) : 20361 a; 20362 }; 20363 20364 20365 /** 20366 * Convert from camel case parameters to Hungarian notation. This is made public 20367 * for the extensions to provide the same ability as DataTables core to accept 20368 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase 20369 * parameters. 20370 * 20371 * @param {object} src The model object which holds all parameters that can be 20372 * mapped. 20373 * @param {object} user The object to convert from camel case to Hungarian. 20374 * @param {boolean} force When set to `true`, properties which already have a 20375 * Hungarian value in the `user` object will be overwritten. Otherwise they 20376 * won't be. 20377 */ 20378 DataTable.camelToHungarian = _fnCamelToHungarian; 20379 20380 20381 20382 /** 20383 * 20384 */ 20385 _api_register( '$()', function ( selector, opts ) { 20386 var 20387 rows = this.rows( opts ).nodes(), // Get all rows 20388 jqRows = $(rows); 20389 20390 return $( [].concat( 20391 jqRows.filter( selector ).toArray(), 20392 jqRows.find( selector ).toArray() 20393 ) ); 20394 } ); 20395 20396 20397 // jQuery functions to operate on the tables 20398 $.each( [ 'on', 'one', 'off' ], function (i, key) { 20399 _api_register( key+'()', function ( /* event, handler */ ) { 20400 var args = Array.prototype.slice.call(arguments); 20401 20402 // Add the `dt` namespace automatically if it isn't already present 20403 args[0] = $.map( args[0].split( /\s/ ), function ( e ) { 20404 return ! e.match(/\.dt\b/) ? 20405 e+'.dt' : 20406 e; 20407 } ).join( ' ' ); 20408 20409 var inst = $( this.tables().nodes() ); 20410 inst[key].apply( inst, args ); 20411 return this; 20412 } ); 20413 } ); 20414 20415 20416 _api_register( 'clear()', function () { 20417 return this.iterator( 'table', function ( settings ) { 20418 _fnClearTable( settings ); 20419 } ); 20420 } ); 20421 20422 20423 _api_register( 'settings()', function () { 20424 return new _Api( this.context, this.context ); 20425 } ); 20426 20427 20428 _api_register( 'init()', function () { 20429 var ctx = this.context; 20430 return ctx.length ? ctx[0].oInit : null; 20431 } ); 20432 20433 20434 _api_register( 'data()', function () { 20435 return this.iterator( 'table', function ( settings ) { 20436 return _pluck( settings.aoData, '_aData' ); 20437 } ).flatten(); 20438 } ); 20439 20440 20441 _api_register( 'destroy()', function ( remove ) { 20442 remove = remove || false; 20443 20444 return this.iterator( 'table', function ( settings ) { 20445 var orig = settings.nTableWrapper.parentNode; 20446 var classes = settings.oClasses; 20447 var table = settings.nTable; 20448 var tbody = settings.nTBody; 20449 var thead = settings.nTHead; 20450 var tfoot = settings.nTFoot; 20451 var jqTable = $(table); 20452 var jqTbody = $(tbody); 20453 var jqWrapper = $(settings.nTableWrapper); 20454 var rows = $.map( settings.aoData, function (r) { return r.nTr; } ); 20455 var i, ien; 20456 20457 // Flag to note that the table is currently being destroyed - no action 20458 // should be taken 20459 settings.bDestroying = true; 20460 20461 // Fire off the destroy callbacks for plug-ins etc 20462 _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] ); 20463 20464 // If not being removed from the document, make all columns visible 20465 if ( ! remove ) { 20466 new _Api( settings ).columns().visible( true ); 20467 } 20468 20469 // Blitz all `DT` namespaced events (these are internal events, the 20470 // lowercase, `dt` events are user subscribed and they are responsible 20471 // for removing them 20472 jqWrapper.off('.DT').find(':not(tbody *)').off('.DT'); 20473 $(window).off('.DT-'+settings.sInstance); 20474 20475 // When scrolling we had to break the table up - restore it 20476 if ( table != thead.parentNode ) { 20477 jqTable.children('thead').detach(); 20478 jqTable.append( thead ); 20479 } 20480 20481 if ( tfoot && table != tfoot.parentNode ) { 20482 jqTable.children('tfoot').detach(); 20483 jqTable.append( tfoot ); 20484 } 20485 20486 settings.aaSorting = []; 20487 settings.aaSortingFixed = []; 20488 _fnSortingClasses( settings ); 20489 20490 $( rows ).removeClass( settings.asStripeClasses.join(' ') ); 20491 20492 $('th, td', thead).removeClass( classes.sSortable+' '+ 20493 classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone 20494 ); 20495 20496 // Add the TR elements back into the table in their original order 20497 jqTbody.children().detach(); 20498 jqTbody.append( rows ); 20499 20500 // Remove the DataTables generated nodes, events and classes 20501 var removedMethod = remove ? 'remove' : 'detach'; 20502 jqTable[ removedMethod ](); 20503 jqWrapper[ removedMethod ](); 20504 20505 // If we need to reattach the table to the document 20506 if ( ! remove && orig ) { 20507 // insertBefore acts like appendChild if !arg[1] 20508 orig.insertBefore( table, settings.nTableReinsertBefore ); 20509 20510 // Restore the width of the original table - was read from the style property, 20511 // so we can restore directly to that 20512 jqTable 20513 .css( 'width', settings.sDestroyWidth ) 20514 .removeClass( classes.sTable ); 20515 20516 // If the were originally stripe classes - then we add them back here. 20517 // Note this is not fool proof (for example if not all rows had stripe 20518 // classes - but it's a good effort without getting carried away 20519 ien = settings.asDestroyStripes.length; 20520 20521 if ( ien ) { 20522 jqTbody.children().each( function (i) { 20523 $(this).addClass( settings.asDestroyStripes[i % ien] ); 20524 } ); 20525 } 20526 } 20527 20528 /* Remove the settings object from the settings array */ 20529 var idx = $.inArray( settings, DataTable.settings ); 20530 if ( idx !== -1 ) { 20531 DataTable.settings.splice( idx, 1 ); 20532 } 20533 } ); 20534 } ); 20535 20536 20537 // Add the `every()` method for rows, columns and cells in a compact form 20538 $.each( [ 'column', 'row', 'cell' ], function ( i, type ) { 20539 _api_register( type+'s().every()', function ( fn ) { 20540 var opts = this.selector.opts; 20541 var api = this; 20542 20543 return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) { 20544 // Rows and columns: 20545 // arg1 - index 20546 // arg2 - table counter 20547 // arg3 - loop counter 20548 // arg4 - undefined 20549 // Cells: 20550 // arg1 - row index 20551 // arg2 - column index 20552 // arg3 - table counter 20553 // arg4 - loop counter 20554 fn.call( 20555 api[ type ]( 20556 arg1, 20557 type==='cell' ? arg2 : opts, 20558 type==='cell' ? opts : undefined 20559 ), 20560 arg1, arg2, arg3, arg4 20561 ); 20562 } ); 20563 } ); 20564 } ); 20565 20566 20567 // i18n method for extensions to be able to use the language object from the 20568 // DataTable 20569 _api_register( 'i18n()', function ( token, def, plural ) { 20570 var ctx = this.context[0]; 20571 var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage ); 20572 20573 if ( resolved === undefined ) { 20574 resolved = def; 20575 } 20576 20577 if ( plural !== undefined && $.isPlainObject( resolved ) ) { 20578 resolved = resolved[ plural ] !== undefined ? 20579 resolved[ plural ] : 20580 resolved._; 20581 } 20582 20583 return resolved.replace( '%d', plural ); // nb: plural might be undefined, 20584 } ); 20585 /** 20586 * Version string for plug-ins to check compatibility. Allowed format is 20587 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used 20588 * only for non-release builds. See http://semver.org/ for more information. 20589 * @member 20590 * @type string 20591 * @default Version number 20592 */ 20593 DataTable.version = "1.11.3"; 20594 20595 /** 20596 * Private data store, containing all of the settings objects that are 20597 * created for the tables on a given page. 20598 * 20599 * Note that the `DataTable.settings` object is aliased to 20600 * `jQuery.fn.dataTableExt` through which it may be accessed and 20601 * manipulated, or `jQuery.fn.dataTable.settings`. 20602 * @member 20603 * @type array 20604 * @default [] 20605 * @private 20606 */ 20607 DataTable.settings = [];
vendor: 69,697 bytes, lines 20608-22798
20608 20609 /** 20610 * Object models container, for the various models that DataTables has 20611 * available to it. These models define the objects that are used to hold 20612 * the active state and configuration of the table. 20613 * @namespace 20614 */ 20615 DataTable.models = {}; 20616 20617 20618 20619 /** 20620 * Template object for the way in which DataTables holds information about 20621 * search information for the global filter and individual column filters. 20622 * @namespace 20623 */ 20624 DataTable.models.oSearch = { 20625 /** 20626 * Flag to indicate if the filtering should be case insensitive or not 20627 * @type boolean 20628 * @default true 20629 */ 20630 "bCaseInsensitive": true, 20631 20632 /** 20633 * Applied search term 20634 * @type string 20635 * @default <i>Empty string</i> 20636 */ 20637 "sSearch": "", 20638 20639 /** 20640 * Flag to indicate if the search term should be interpreted as a 20641 * regular expression (true) or not (false) and therefore and special 20642 * regex characters escaped. 20643 * @type boolean 20644 * @default false 20645 */ 20646 "bRegex": false, 20647 20648 /** 20649 * Flag to indicate if DataTables is to use its smart filtering or not. 20650 * @type boolean 20651 * @default true 20652 */ 20653 "bSmart": true, 20654 20655 /** 20656 * Flag to indicate if DataTables should only trigger a search when 20657 * the return key is pressed. 20658 * @type boolean 20659 * @default false 20660 */ 20661 "return": false 20662 }; 20663 20664 20665 20666 20667 /** 20668 * Template object for the way in which DataTables holds information about 20669 * each individual row. This is the object format used for the settings 20670 * aoData array. 20671 * @namespace 20672 */ 20673 DataTable.models.oRow = { 20674 /** 20675 * TR element for the row 20676 * @type node 20677 * @default null 20678 */ 20679 "nTr": null, 20680 20681 /** 20682 * Array of TD elements for each row. This is null until the row has been 20683 * created. 20684 * @type array nodes 20685 * @default [] 20686 */ 20687 "anCells": null, 20688 20689 /** 20690 * Data object from the original data source for the row. This is either 20691 * an array if using the traditional form of DataTables, or an object if 20692 * using mData options. The exact type will depend on the passed in 20693 * data from the data source, or will be an array if using DOM a data 20694 * source. 20695 * @type array|object 20696 * @default [] 20697 */ 20698 "_aData": [], 20699 20700 /** 20701 * Sorting data cache - this array is ostensibly the same length as the 20702 * number of columns (although each index is generated only as it is 20703 * needed), and holds the data that is used for sorting each column in the 20704 * row. We do this cache generation at the start of the sort in order that 20705 * the formatting of the sort data need be done only once for each cell 20706 * per sort. This array should not be read from or written to by anything 20707 * other than the master sorting methods. 20708 * @type array 20709 * @default null 20710 * @private 20711 */ 20712 "_aSortData": null, 20713 20714 /** 20715 * Per cell filtering data cache. As per the sort data cache, used to 20716 * increase the performance of the filtering in DataTables 20717 * @type array 20718 * @default null 20719 * @private 20720 */ 20721 "_aFilterData": null, 20722 20723 /** 20724 * Filtering data cache. This is the same as the cell filtering cache, but 20725 * in this case a string rather than an array. This is easily computed with 20726 * a join on `_aFilterData`, but is provided as a cache so the join isn't 20727 * needed on every search (memory traded for performance) 20728 * @type array 20729 * @default null 20730 * @private 20731 */ 20732 "_sFilterRow": null, 20733 20734 /** 20735 * Cache of the class name that DataTables has applied to the row, so we 20736 * can quickly look at this variable rather than needing to do a DOM check 20737 * on className for the nTr property. 20738 * @type string 20739 * @default <i>Empty string</i> 20740 * @private 20741 */ 20742 "_sRowStripe": "", 20743 20744 /** 20745 * Denote if the original data source was from the DOM, or the data source 20746 * object. This is used for invalidating data, so DataTables can 20747 * automatically read data from the original source, unless uninstructed 20748 * otherwise. 20749 * @type string 20750 * @default null 20751 * @private 20752 */ 20753 "src": null, 20754 20755 /** 20756 * Index in the aoData array. This saves an indexOf lookup when we have the 20757 * object, but want to know the index 20758 * @type integer 20759 * @default -1 20760 * @private 20761 */ 20762 "idx": -1 20763 }; 20764 20765 20766 /** 20767 * Template object for the column information object in DataTables. This object 20768 * is held in the settings aoColumns array and contains all the information that 20769 * DataTables needs about each individual column. 20770 * 20771 * Note that this object is related to {@link DataTable.defaults.column} 20772 * but this one is the internal data store for DataTables's cache of columns. 20773 * It should NOT be manipulated outside of DataTables. Any configuration should 20774 * be done through the initialisation options. 20775 * @namespace 20776 */ 20777 DataTable.models.oColumn = { 20778 /** 20779 * Column index. This could be worked out on-the-fly with $.inArray, but it 20780 * is faster to just hold it as a variable 20781 * @type integer 20782 * @default null 20783 */ 20784 "idx": null, 20785 20786 /** 20787 * A list of the columns that sorting should occur on when this column 20788 * is sorted. That this property is an array allows multi-column sorting 20789 * to be defined for a column (for example first name / last name columns 20790 * would benefit from this). The values are integers pointing to the 20791 * columns to be sorted on (typically it will be a single integer pointing 20792 * at itself, but that doesn't need to be the case). 20793 * @type array 20794 */ 20795 "aDataSort": null, 20796 20797 /** 20798 * Define the sorting directions that are applied to the column, in sequence 20799 * as the column is repeatedly sorted upon - i.e. the first value is used 20800 * as the sorting direction when the column if first sorted (clicked on). 20801 * Sort it again (click again) and it will move on to the next index. 20802 * Repeat until loop. 20803 * @type array 20804 */ 20805 "asSorting": null, 20806 20807 /** 20808 * Flag to indicate if the column is searchable, and thus should be included 20809 * in the filtering or not. 20810 * @type boolean 20811 */ 20812 "bSearchable": null, 20813 20814 /** 20815 * Flag to indicate if the column is sortable or not. 20816 * @type boolean 20817 */ 20818 "bSortable": null, 20819 20820 /** 20821 * Flag to indicate if the column is currently visible in the table or not 20822 * @type boolean 20823 */ 20824 "bVisible": null, 20825 20826 /** 20827 * Store for manual type assignment using the `column.type` option. This 20828 * is held in store so we can manipulate the column's `sType` property. 20829 * @type string 20830 * @default null 20831 * @private 20832 */ 20833 "_sManualType": null, 20834 20835 /** 20836 * Flag to indicate if HTML5 data attributes should be used as the data 20837 * source for filtering or sorting. True is either are. 20838 * @type boolean 20839 * @default false 20840 * @private 20841 */ 20842 "_bAttrSrc": false, 20843 20844 /** 20845 * Developer definable function that is called whenever a cell is created (Ajax source, 20846 * etc) or processed for input (DOM source). This can be used as a compliment to mRender 20847 * allowing you to modify the DOM element (add background colour for example) when the 20848 * element is available. 20849 * @type function 20850 * @param {element} nTd The TD node that has been created 20851 * @param {*} sData The Data for the cell 20852 * @param {array|object} oData The data for the whole row 20853 * @param {int} iRow The row index for the aoData data store 20854 * @default null 20855 */ 20856 "fnCreatedCell": null, 20857 20858 /** 20859 * Function to get data from a cell in a column. You should <b>never</b> 20860 * access data directly through _aData internally in DataTables - always use 20861 * the method attached to this property. It allows mData to function as 20862 * required. This function is automatically assigned by the column 20863 * initialisation method 20864 * @type function 20865 * @param {array|object} oData The data array/object for the array 20866 * (i.e. aoData[]._aData) 20867 * @param {string} sSpecific The specific data type you want to get - 20868 * 'display', 'type' 'filter' 'sort' 20869 * @returns {*} The data for the cell from the given row's data 20870 * @default null 20871 */ 20872 "fnGetData": null, 20873 20874 /** 20875 * Function to set data for a cell in the column. You should <b>never</b> 20876 * set the data directly to _aData internally in DataTables - always use 20877 * this method. It allows mData to function as required. This function 20878 * is automatically assigned by the column initialisation method 20879 * @type function 20880 * @param {array|object} oData The data array/object for the array 20881 * (i.e. aoData[]._aData) 20882 * @param {*} sValue Value to set 20883 * @default null 20884 */ 20885 "fnSetData": null, 20886 20887 /** 20888 * Property to read the value for the cells in the column from the data 20889 * source array / object. If null, then the default content is used, if a 20890 * function is given then the return from the function is used. 20891 * @type function|int|string|null 20892 * @default null 20893 */ 20894 "mData": null, 20895 20896 /** 20897 * Partner property to mData which is used (only when defined) to get 20898 * the data - i.e. it is basically the same as mData, but without the 20899 * 'set' option, and also the data fed to it is the result from mData. 20900 * This is the rendering method to match the data method of mData. 20901 * @type function|int|string|null 20902 * @default null 20903 */ 20904 "mRender": null, 20905 20906 /** 20907 * Unique header TH/TD element for this column - this is what the sorting 20908 * listener is attached to (if sorting is enabled.) 20909 * @type node 20910 * @default null 20911 */ 20912 "nTh": null, 20913 20914 /** 20915 * Unique footer TH/TD element for this column (if there is one). Not used 20916 * in DataTables as such, but can be used for plug-ins to reference the 20917 * footer for each column. 20918 * @type node 20919 * @default null 20920 */ 20921 "nTf": null, 20922 20923 /** 20924 * The class to apply to all TD elements in the table's TBODY for the column 20925 * @type string 20926 * @default null 20927 */ 20928 "sClass": null, 20929 20930 /** 20931 * When DataTables calculates the column widths to assign to each column, 20932 * it finds the longest string in each column and then constructs a 20933 * temporary table and reads the widths from that. The problem with this 20934 * is that "mmm" is much wider then "iiii", but the latter is a longer 20935 * string - thus the calculation can go wrong (doing it properly and putting 20936 * it into an DOM object and measuring that is horribly(!) slow). Thus as 20937 * a "work around" we provide this option. It will append its value to the 20938 * text that is found to be the longest string for the column - i.e. padding. 20939 * @type string 20940 */ 20941 "sContentPadding": null, 20942 20943 /** 20944 * Allows a default value to be given for a column's data, and will be used 20945 * whenever a null data source is encountered (this can be because mData 20946 * is set to null, or because the data source itself is null). 20947 * @type string 20948 * @default null 20949 */ 20950 "sDefaultContent": null, 20951 20952 /** 20953 * Name for the column, allowing reference to the column by name as well as 20954 * by index (needs a lookup to work by name). 20955 * @type string 20956 */ 20957 "sName": null, 20958 20959 /** 20960 * Custom sorting data type - defines which of the available plug-ins in 20961 * afnSortData the custom sorting will use - if any is defined. 20962 * @type string 20963 * @default std 20964 */ 20965 "sSortDataType": 'std', 20966 20967 /** 20968 * Class to be applied to the header element when sorting on this column 20969 * @type string 20970 * @default null 20971 */ 20972 "sSortingClass": null, 20973 20974 /** 20975 * Class to be applied to the header element when sorting on this column - 20976 * when jQuery UI theming is used. 20977 * @type string 20978 * @default null 20979 */ 20980 "sSortingClassJUI": null, 20981 20982 /** 20983 * Title of the column - what is seen in the TH element (nTh). 20984 * @type string 20985 */ 20986 "sTitle": null, 20987 20988 /** 20989 * Column sorting and filtering type 20990 * @type string 20991 * @default null 20992 */ 20993 "sType": null, 20994 20995 /** 20996 * Width of the column 20997 * @type string 20998 * @default null 20999 */ 21000 "sWidth": null, 21001 21002 /** 21003 * Width of the column when it was first "encountered" 21004 * @type string 21005 * @default null 21006 */ 21007 "sWidthOrig": null 21008 }; 21009 21010 21011 /* 21012 * Developer note: The properties of the object below are given in Hungarian 21013 * notation, that was used as the interface for DataTables prior to v1.10, however 21014 * from v1.10 onwards the primary interface is camel case. In order to avoid 21015 * breaking backwards compatibility utterly with this change, the Hungarian 21016 * version is still, internally the primary interface, but is is not documented 21017 * - hence the @name tags in each doc comment. This allows a Javascript function 21018 * to create a map from Hungarian notation to camel case (going the other direction 21019 * would require each property to be listed, which would add around 3K to the size 21020 * of DataTables, while this method is about a 0.5K hit). 21021 * 21022 * Ultimately this does pave the way for Hungarian notation to be dropped 21023 * completely, but that is a massive amount of work and will break current 21024 * installs (therefore is on-hold until v2). 21025 */ 21026 21027 /** 21028 * Initialisation options that can be given to DataTables at initialisation 21029 * time. 21030 * @namespace 21031 */ 21032 DataTable.defaults = { 21033 /** 21034 * An array of data to use for the table, passed in at initialisation which 21035 * will be used in preference to any data which is already in the DOM. This is 21036 * particularly useful for constructing tables purely in Javascript, for 21037 * example with a custom Ajax call. 21038 * @type array 21039 * @default null 21040 * 21041 * @dtopt Option 21042 * @name DataTable.defaults.data 21043 * 21044 * @example 21045 * // Using a 2D array data source 21046 * $(document).ready( function () { 21047 * $('#example').dataTable( { 21048 * "data": [ 21049 * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'], 21050 * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'], 21051 * ], 21052 * "columns": [ 21053 * { "title": "Engine" }, 21054 * { "title": "Browser" }, 21055 * { "title": "Platform" }, 21056 * { "title": "Version" }, 21057 * { "title": "Grade" } 21058 * ] 21059 * } ); 21060 * } ); 21061 * 21062 * @example 21063 * // Using an array of objects as a data source (`data`) 21064 * $(document).ready( function () { 21065 * $('#example').dataTable( { 21066 * "data": [ 21067 * { 21068 * "engine": "Trident", 21069 * "browser": "Internet Explorer 4.0", 21070 * "platform": "Win 95+", 21071 * "version": 4, 21072 * "grade": "X" 21073 * }, 21074 * { 21075 * "engine": "Trident", 21076 * "browser": "Internet Explorer 5.0", 21077 * "platform": "Win 95+", 21078 * "version": 5, 21079 * "grade": "C" 21080 * } 21081 * ], 21082 * "columns": [ 21083 * { "title": "Engine", "data": "engine" }, 21084 * { "title": "Browser", "data": "browser" }, 21085 * { "title": "Platform", "data": "platform" }, 21086 * { "title": "Version", "data": "version" }, 21087 * { "title": "Grade", "data": "grade" } 21088 * ] 21089 * } ); 21090 * } ); 21091 */ 21092 "aaData": null, 21093 21094 21095 /** 21096 * If ordering is enabled, then DataTables will perform a first pass sort on 21097 * initialisation. You can define which column(s) the sort is performed 21098 * upon, and the sorting direction, with this variable. The `sorting` array 21099 * should contain an array for each column to be sorted initially containing 21100 * the column's index and a direction string ('asc' or 'desc'). 21101 * @type array 21102 * @default [[0,'asc']] 21103 * 21104 * @dtopt Option 21105 * @name DataTable.defaults.order 21106 * 21107 * @example 21108 * // Sort by 3rd column first, and then 4th column 21109 * $(document).ready( function() { 21110 * $('#example').dataTable( { 21111 * "order": [[2,'asc'], [3,'desc']] 21112 * } ); 21113 * } ); 21114 * 21115 * // No initial sorting 21116 * $(document).ready( function() { 21117 * $('#example').dataTable( { 21118 * "order": [] 21119 * } ); 21120 * } ); 21121 */ 21122 "aaSorting": [[0,'asc']], 21123 21124 21125 /** 21126 * This parameter is basically identical to the `sorting` parameter, but 21127 * cannot be overridden by user interaction with the table. What this means 21128 * is that you could have a column (visible or hidden) which the sorting 21129 * will always be forced on first - any sorting after that (from the user) 21130 * will then be performed as required. This can be useful for grouping rows 21131 * together. 21132 * @type array 21133 * @default null 21134 * 21135 * @dtopt Option 21136 * @name DataTable.defaults.orderFixed 21137 * 21138 * @example 21139 * $(document).ready( function() { 21140 * $('#example').dataTable( { 21141 * "orderFixed": [[0,'asc']] 21142 * } ); 21143 * } ) 21144 */ 21145 "aaSortingFixed": [], 21146 21147 21148 /** 21149 * DataTables can be instructed to load data to display in the table from a 21150 * Ajax source. This option defines how that Ajax call is made and where to. 21151 * 21152 * The `ajax` property has three different modes of operation, depending on 21153 * how it is defined. These are: 21154 * 21155 * * `string` - Set the URL from where the data should be loaded from. 21156 * * `object` - Define properties for `jQuery.ajax`. 21157 * * `function` - Custom data get function 21158 * 21159 * `string` 21160 * -------- 21161 * 21162 * As a string, the `ajax` property simply defines the URL from which 21163 * DataTables will load data. 21164 * 21165 * `object` 21166 * -------- 21167 * 21168 * As an object, the parameters in the object are passed to 21169 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control 21170 * of the Ajax request. DataTables has a number of default parameters which 21171 * you can override using this option. Please refer to the jQuery 21172 * documentation for a full description of the options available, although 21173 * the following parameters provide additional options in DataTables or 21174 * require special consideration: 21175 * 21176 * * `data` - As with jQuery, `data` can be provided as an object, but it 21177 * can also be used as a function to manipulate the data DataTables sends 21178 * to the server. The function takes a single parameter, an object of 21179 * parameters with the values that DataTables has readied for sending. An 21180 * object may be returned which will be merged into the DataTables 21181 * defaults, or you can add the items to the object that was passed in and 21182 * not return anything from the function. This supersedes `fnServerParams` 21183 * from DataTables 1.9-. 21184 * 21185 * * `dataSrc` - By default DataTables will look for the property `data` (or 21186 * `aaData` for compatibility with DataTables 1.9-) when obtaining data 21187 * from an Ajax source or for server-side processing - this parameter 21188 * allows that property to be changed. You can use Javascript dotted 21189 * object notation to get a data source for multiple levels of nesting, or 21190 * it my be used as a function. As a function it takes a single parameter, 21191 * the JSON returned from the server, which can be manipulated as 21192 * required, with the returned value being that used by DataTables as the 21193 * data source for the table. This supersedes `sAjaxDataProp` from 21194 * DataTables 1.9-. 21195 * 21196 * * `success` - Should not be overridden it is used internally in 21197 * DataTables. To manipulate / transform the data returned by the server 21198 * use `ajax.dataSrc`, or use `ajax` as a function (see below). 21199 * 21200 * `function` 21201 * ---------- 21202 * 21203 * As a function, making the Ajax call is left up to yourself allowing 21204 * complete control of the Ajax request. Indeed, if desired, a method other 21205 * than Ajax could be used to obtain the required data, such as Web storage 21206 * or an AIR database. 21207 * 21208 * The function is given four parameters and no return is required. The 21209 * parameters are: 21210 * 21211 * 1. _object_ - Data to send to the server 21212 * 2. _function_ - Callback function that must be executed when the required 21213 * data has been obtained. That data should be passed into the callback 21214 * as the only parameter 21215 * 3. _object_ - DataTables settings object for the table 21216 * 21217 * Note that this supersedes `fnServerData` from DataTables 1.9-. 21218 * 21219 * @type string|object|function 21220 * @default null 21221 * 21222 * @dtopt Option 21223 * @name DataTable.defaults.ajax 21224 * @since 1.10.0 21225 * 21226 * @example 21227 * // Get JSON data from a file via Ajax. 21228 * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default). 21229 * $('#example').dataTable( { 21230 * "ajax": "data.json" 21231 * } ); 21232 * 21233 * @example 21234 * // Get JSON data from a file via Ajax, using `dataSrc` to change 21235 * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`) 21236 * $('#example').dataTable( { 21237 * "ajax": { 21238 * "url": "data.json", 21239 * "dataSrc": "tableData" 21240 * } 21241 * } ); 21242 * 21243 * @example 21244 * // Get JSON data from a file via Ajax, using `dataSrc` to read data 21245 * // from a plain array rather than an array in an object 21246 * $('#example').dataTable( { 21247 * "ajax": { 21248 * "url": "data.json", 21249 * "dataSrc": "" 21250 * } 21251 * } ); 21252 * 21253 * @example 21254 * // Manipulate the data returned from the server - add a link to data 21255 * // (note this can, should, be done using `render` for the column - this 21256 * // is just a simple example of how the data can be manipulated). 21257 * $('#example').dataTable( { 21258 * "ajax": { 21259 * "url": "data.json", 21260 * "dataSrc": function ( json ) { 21261 * for ( var i=0, ien=json.length ; i<ien ; i++ ) { 21262 * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>'; 21263 * } 21264 * return json; 21265 * } 21266 * } 21267 * } ); 21268 * 21269 * @example 21270 * // Add data to the request 21271 * $('#example').dataTable( { 21272 * "ajax": { 21273 * "url": "data.json", 21274 * "data": function ( d ) { 21275 * return { 21276 * "extra_search": $('#extra').val() 21277 * }; 21278 * } 21279 * } 21280 * } ); 21281 * 21282 * @example 21283 * // Send request as POST 21284 * $('#example').dataTable( { 21285 * "ajax": { 21286 * "url": "data.json", 21287 * "type": "POST" 21288 * } 21289 * } ); 21290 * 21291 * @example 21292 * // Get the data from localStorage (could interface with a form for 21293 * // adding, editing and removing rows). 21294 * $('#example').dataTable( { 21295 * "ajax": function (data, callback, settings) { 21296 * callback( 21297 * JSON.parse( localStorage.getItem('dataTablesData') ) 21298 * ); 21299 * } 21300 * } ); 21301 */ 21302 "ajax": null, 21303 21304 21305 /** 21306 * This parameter allows you to readily specify the entries in the length drop 21307 * down menu that DataTables shows when pagination is enabled. It can be 21308 * either a 1D array of options which will be used for both the displayed 21309 * option and the value, or a 2D array which will use the array in the first 21310 * position as the value, and the array in the second position as the 21311 * displayed options (useful for language strings such as 'All'). 21312 * 21313 * Note that the `pageLength` property will be automatically set to the 21314 * first value given in this array, unless `pageLength` is also provided. 21315 * @type array 21316 * @default [ 10, 25, 50, 100 ] 21317 * 21318 * @dtopt Option 21319 * @name DataTable.defaults.lengthMenu 21320 * 21321 * @example 21322 * $(document).ready( function() { 21323 * $('#example').dataTable( { 21324 * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] 21325 * } ); 21326 * } ); 21327 */ 21328 "aLengthMenu": [ 10, 25, 50, 100 ], 21329 21330 21331 /** 21332 * The `columns` option in the initialisation parameter allows you to define 21333 * details about the way individual columns behave. For a full list of 21334 * column options that can be set, please see 21335 * {@link DataTable.defaults.column}. Note that if you use `columns` to 21336 * define your columns, you must have an entry in the array for every single 21337 * column that you have in your table (these can be null if you don't which 21338 * to specify any options). 21339 * @member 21340 * 21341 * @name DataTable.defaults.column 21342 */ 21343 "aoColumns": null, 21344 21345 /** 21346 * Very similar to `columns`, `columnDefs` allows you to target a specific 21347 * column, multiple columns, or all columns, using the `targets` property of 21348 * each object in the array. This allows great flexibility when creating 21349 * tables, as the `columnDefs` arrays can be of any length, targeting the 21350 * columns you specifically want. `columnDefs` may use any of the column 21351 * options available: {@link DataTable.defaults.column}, but it _must_ 21352 * have `targets` defined in each object in the array. Values in the `targets` 21353 * array may be: 21354 * <ul> 21355 * <li>a string - class name will be matched on the TH for the column</li> 21356 * <li>0 or a positive integer - column index counting from the left</li> 21357 * <li>a negative integer - column index counting from the right</li> 21358 * <li>the string "_all" - all columns (i.e. assign a default)</li> 21359 * </ul> 21360 * @member 21361 * 21362 * @name DataTable.defaults.columnDefs 21363 */ 21364 "aoColumnDefs": null, 21365 21366 21367 /** 21368 * Basically the same as `search`, this parameter defines the individual column 21369 * filtering state at initialisation time. The array must be of the same size 21370 * as the number of columns, and each element be an object with the parameters 21371 * `search` and `escapeRegex` (the latter is optional). 'null' is also 21372 * accepted and the default will be used. 21373 * @type array 21374 * @default [] 21375 * 21376 * @dtopt Option 21377 * @name DataTable.defaults.searchCols 21378 * 21379 * @example 21380 * $(document).ready( function() { 21381 * $('#example').dataTable( { 21382 * "searchCols": [ 21383 * null, 21384 * { "search": "My filter" }, 21385 * null, 21386 * { "search": "^[0-9]", "escapeRegex": false } 21387 * ] 21388 * } ); 21389 * } ) 21390 */ 21391 "aoSearchCols": [], 21392 21393 21394 /** 21395 * An array of CSS classes that should be applied to displayed rows. This 21396 * array may be of any length, and DataTables will apply each class 21397 * sequentially, looping when required. 21398 * @type array 21399 * @default null <i>Will take the values determined by the `oClasses.stripe*` 21400 * options</i> 21401 * 21402 * @dtopt Option 21403 * @name DataTable.defaults.stripeClasses 21404 * 21405 * @example 21406 * $(document).ready( function() { 21407 * $('#example').dataTable( { 21408 * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ] 21409 * } ); 21410 * } ) 21411 */ 21412 "asStripeClasses": null, 21413 21414 21415 /** 21416 * Enable or disable automatic column width calculation. This can be disabled 21417 * as an optimisation (it takes some time to calculate the widths) if the 21418 * tables widths are passed in using `columns`. 21419 * @type boolean 21420 * @default true 21421 * 21422 * @dtopt Features 21423 * @name DataTable.defaults.autoWidth 21424 * 21425 * @example 21426 * $(document).ready( function () { 21427 * $('#example').dataTable( { 21428 * "autoWidth": false 21429 * } ); 21430 * } ); 21431 */ 21432 "bAutoWidth": true, 21433 21434 21435 /** 21436 * Deferred rendering can provide DataTables with a huge speed boost when you 21437 * are using an Ajax or JS data source for the table. This option, when set to 21438 * true, will cause DataTables to defer the creation of the table elements for 21439 * each row until they are needed for a draw - saving a significant amount of 21440 * time. 21441 * @type boolean 21442 * @default false 21443 * 21444 * @dtopt Features 21445 * @name DataTable.defaults.deferRender 21446 * 21447 * @example 21448 * $(document).ready( function() { 21449 * $('#example').dataTable( { 21450 * "ajax": "sources/arrays.txt", 21451 * "deferRender": true 21452 * } ); 21453 * } ); 21454 */ 21455 "bDeferRender": false, 21456 21457 21458 /** 21459 * Replace a DataTable which matches the given selector and replace it with 21460 * one which has the properties of the new initialisation object passed. If no 21461 * table matches the selector, then the new DataTable will be constructed as 21462 * per normal. 21463 * @type boolean 21464 * @default false 21465 * 21466 * @dtopt Options 21467 * @name DataTable.defaults.destroy 21468 * 21469 * @example 21470 * $(document).ready( function() { 21471 * $('#example').dataTable( { 21472 * "srollY": "200px", 21473 * "paginate": false 21474 * } ); 21475 * 21476 * // Some time later.... 21477 * $('#example').dataTable( { 21478 * "filter": false, 21479 * "destroy": true 21480 * } ); 21481 * } ); 21482 */ 21483 "bDestroy": false, 21484 21485 21486 /** 21487 * Enable or disable filtering of data. Filtering in DataTables is "smart" in 21488 * that it allows the end user to input multiple words (space separated) and 21489 * will match a row containing those words, even if not in the order that was 21490 * specified (this allow matching across multiple columns). Note that if you 21491 * wish to use filtering in DataTables this must remain 'true' - to remove the 21492 * default filtering input box and retain filtering abilities, please use 21493 * {@link DataTable.defaults.dom}. 21494 * @type boolean 21495 * @default true 21496 * 21497 * @dtopt Features 21498 * @name DataTable.defaults.searching 21499 * 21500 * @example 21501 * $(document).ready( function () { 21502 * $('#example').dataTable( { 21503 * "searching": false 21504 * } ); 21505 * } ); 21506 */ 21507 "bFilter": true, 21508 21509 21510 /** 21511 * Enable or disable the table information display. This shows information 21512 * about the data that is currently visible on the page, including information 21513 * about filtered data if that action is being performed. 21514 * @type boolean 21515 * @default true 21516 * 21517 * @dtopt Features 21518 * @name DataTable.defaults.info 21519 * 21520 * @example 21521 * $(document).ready( function () { 21522 * $('#example').dataTable( { 21523 * "info": false 21524 * } ); 21525 * } ); 21526 */ 21527 "bInfo": true, 21528 21529 21530 /** 21531 * Allows the end user to select the size of a formatted page from a select 21532 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`). 21533 * @type boolean 21534 * @default true 21535 * 21536 * @dtopt Features 21537 * @name DataTable.defaults.lengthChange 21538 * 21539 * @example 21540 * $(document).ready( function () { 21541 * $('#example').dataTable( { 21542 * "lengthChange": false 21543 * } ); 21544 * } ); 21545 */ 21546 "bLengthChange": true, 21547 21548 21549 /** 21550 * Enable or disable pagination. 21551 * @type boolean 21552 * @default true 21553 * 21554 * @dtopt Features 21555 * @name DataTable.defaults.paging 21556 * 21557 * @example 21558 * $(document).ready( function () { 21559 * $('#example').dataTable( { 21560 * "paging": false 21561 * } ); 21562 * } ); 21563 */ 21564 "bPaginate": true, 21565 21566 21567 /** 21568 * Enable or disable the display of a 'processing' indicator when the table is 21569 * being processed (e.g. a sort). This is particularly useful for tables with 21570 * large amounts of data where it can take a noticeable amount of time to sort 21571 * the entries. 21572 * @type boolean 21573 * @default false 21574 * 21575 * @dtopt Features 21576 * @name DataTable.defaults.processing 21577 * 21578 * @example 21579 * $(document).ready( function () { 21580 * $('#example').dataTable( { 21581 * "processing": true 21582 * } ); 21583 * } ); 21584 */ 21585 "bProcessing": false, 21586 21587 21588 /** 21589 * Retrieve the DataTables object for the given selector. Note that if the 21590 * table has already been initialised, this parameter will cause DataTables 21591 * to simply return the object that has already been set up - it will not take 21592 * account of any changes you might have made to the initialisation object 21593 * passed to DataTables (setting this parameter to true is an acknowledgement 21594 * that you understand this). `destroy` can be used to reinitialise a table if 21595 * you need. 21596 * @type boolean 21597 * @default false 21598 * 21599 * @dtopt Options 21600 * @name DataTable.defaults.retrieve 21601 * 21602 * @example 21603 * $(document).ready( function() { 21604 * initTable(); 21605 * tableActions(); 21606 * } ); 21607 * 21608 * function initTable () 21609 * { 21610 * return $('#example').dataTable( { 21611 * "scrollY": "200px", 21612 * "paginate": false, 21613 * "retrieve": true 21614 * } ); 21615 * } 21616 * 21617 * function tableActions () 21618 * { 21619 * var table = initTable(); 21620 * // perform API operations with oTable 21621 * } 21622 */ 21623 "bRetrieve": false, 21624 21625 21626 /** 21627 * When vertical (y) scrolling is enabled, DataTables will force the height of 21628 * the table's viewport to the given height at all times (useful for layout). 21629 * However, this can look odd when filtering data down to a small data set, 21630 * and the footer is left "floating" further down. This parameter (when 21631 * enabled) will cause DataTables to collapse the table's viewport down when 21632 * the result set will fit within the given Y height. 21633 * @type boolean 21634 * @default false 21635 * 21636 * @dtopt Options 21637 * @name DataTable.defaults.scrollCollapse 21638 * 21639 * @example 21640 * $(document).ready( function() { 21641 * $('#example').dataTable( { 21642 * "scrollY": "200", 21643 * "scrollCollapse": true 21644 * } ); 21645 * } ); 21646 */ 21647 "bScrollCollapse": false, 21648 21649 21650 /** 21651 * Configure DataTables to use server-side processing. Note that the 21652 * `ajax` parameter must also be given in order to give DataTables a 21653 * source to obtain the required data for each draw. 21654 * @type boolean 21655 * @default false 21656 * 21657 * @dtopt Features 21658 * @dtopt Server-side 21659 * @name DataTable.defaults.serverSide 21660 * 21661 * @example 21662 * $(document).ready( function () { 21663 * $('#example').dataTable( { 21664 * "serverSide": true, 21665 * "ajax": "xhr.php" 21666 * } ); 21667 * } ); 21668 */ 21669 "bServerSide": false, 21670 21671 21672 /** 21673 * Enable or disable sorting of columns. Sorting of individual columns can be 21674 * disabled by the `sortable` option for each column. 21675 * @type boolean 21676 * @default true 21677 * 21678 * @dtopt Features 21679 * @name DataTable.defaults.ordering 21680 * 21681 * @example 21682 * $(document).ready( function () { 21683 * $('#example').dataTable( { 21684 * "ordering": false 21685 * } ); 21686 * } ); 21687 */ 21688 "bSort": true, 21689 21690 21691 /** 21692 * Enable or display DataTables' ability to sort multiple columns at the 21693 * same time (activated by shift-click by the user). 21694 * @type boolean 21695 * @default true 21696 * 21697 * @dtopt Options 21698 * @name DataTable.defaults.orderMulti 21699 * 21700 * @example 21701 * // Disable multiple column sorting ability 21702 * $(document).ready( function () { 21703 * $('#example').dataTable( { 21704 * "orderMulti": false 21705 * } ); 21706 * } ); 21707 */ 21708 "bSortMulti": true, 21709 21710 21711 /** 21712 * Allows control over whether DataTables should use the top (true) unique 21713 * cell that is found for a single column, or the bottom (false - default). 21714 * This is useful when using complex headers. 21715 * @type boolean 21716 * @default false 21717 * 21718 * @dtopt Options 21719 * @name DataTable.defaults.orderCellsTop 21720 * 21721 * @example 21722 * $(document).ready( function() { 21723 * $('#example').dataTable( { 21724 * "orderCellsTop": true 21725 * } ); 21726 * } ); 21727 */ 21728 "bSortCellsTop": false, 21729 21730 21731 /** 21732 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and 21733 * `sorting\_3` to the columns which are currently being sorted on. This is 21734 * presented as a feature switch as it can increase processing time (while 21735 * classes are removed and added) so for large data sets you might want to 21736 * turn this off. 21737 * @type boolean 21738 * @default true 21739 * 21740 * @dtopt Features 21741 * @name DataTable.defaults.orderClasses 21742 * 21743 * @example 21744 * $(document).ready( function () { 21745 * $('#example').dataTable( { 21746 * "orderClasses": false 21747 * } ); 21748 * } ); 21749 */ 21750 "bSortClasses": true, 21751 21752 21753 /** 21754 * Enable or disable state saving. When enabled HTML5 `localStorage` will be 21755 * used to save table display information such as pagination information, 21756 * display length, filtering and sorting. As such when the end user reloads 21757 * the page the display display will match what thy had previously set up. 21758 * 21759 * Due to the use of `localStorage` the default state saving is not supported 21760 * in IE6 or 7. If state saving is required in those browsers, use 21761 * `stateSaveCallback` to provide a storage solution such as cookies. 21762 * @type boolean 21763 * @default false 21764 * 21765 * @dtopt Features 21766 * @name DataTable.defaults.stateSave 21767 * 21768 * @example 21769 * $(document).ready( function () { 21770 * $('#example').dataTable( { 21771 * "stateSave": true 21772 * } ); 21773 * } ); 21774 */ 21775 "bStateSave": false, 21776 21777 21778 /** 21779 * This function is called when a TR element is created (and all TD child 21780 * elements have been inserted), or registered if using a DOM source, allowing 21781 * manipulation of the TR element (adding classes etc). 21782 * @type function 21783 * @param {node} row "TR" element for the current row 21784 * @param {array} data Raw data array for this row 21785 * @param {int} dataIndex The index of this row in the internal aoData array 21786 * 21787 * @dtopt Callbacks 21788 * @name DataTable.defaults.createdRow 21789 * 21790 * @example 21791 * $(document).ready( function() { 21792 * $('#example').dataTable( { 21793 * "createdRow": function( row, data, dataIndex ) { 21794 * // Bold the grade for all 'A' grade browsers 21795 * if ( data[4] == "A" ) 21796 * { 21797 * $('td:eq(4)', row).html( '<b>A</b>' ); 21798 * } 21799 * } 21800 * } ); 21801 * } ); 21802 */ 21803 "fnCreatedRow": null, 21804 21805 21806 /** 21807 * This function is called on every 'draw' event, and allows you to 21808 * dynamically modify any aspect you want about the created DOM. 21809 * @type function 21810 * @param {object} settings DataTables settings object 21811 * 21812 * @dtopt Callbacks 21813 * @name DataTable.defaults.drawCallback 21814 * 21815 * @example 21816 * $(document).ready( function() { 21817 * $('#example').dataTable( { 21818 * "drawCallback": function( settings ) { 21819 * alert( 'DataTables has redrawn the table' ); 21820 * } 21821 * } ); 21822 * } ); 21823 */ 21824 "fnDrawCallback": null, 21825 21826 21827 /** 21828 * Identical to fnHeaderCallback() but for the table footer this function 21829 * allows you to modify the table footer on every 'draw' event. 21830 * @type function 21831 * @param {node} foot "TR" element for the footer 21832 * @param {array} data Full table data (as derived from the original HTML) 21833 * @param {int} start Index for the current display starting point in the 21834 * display array 21835 * @param {int} end Index for the current display ending point in the 21836 * display array 21837 * @param {array int} display Index array to translate the visual position 21838 * to the full data array 21839 * 21840 * @dtopt Callbacks 21841 * @name DataTable.defaults.footerCallback 21842 * 21843 * @example 21844 * $(document).ready( function() { 21845 * $('#example').dataTable( { 21846 * "footerCallback": function( tfoot, data, start, end, display ) { 21847 * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start; 21848 * } 21849 * } ); 21850 * } ) 21851 */ 21852 "fnFooterCallback": null, 21853 21854 21855 /** 21856 * When rendering large numbers in the information element for the table 21857 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers 21858 * to have a comma separator for the 'thousands' units (e.g. 1 million is 21859 * rendered as "1,000,000") to help readability for the end user. This 21860 * function will override the default method DataTables uses. 21861 * @type function 21862 * @member 21863 * @param {int} toFormat number to be formatted 21864 * @returns {string} formatted string for DataTables to show the number 21865 * 21866 * @dtopt Callbacks 21867 * @name DataTable.defaults.formatNumber 21868 * 21869 * @example 21870 * // Format a number using a single quote for the separator (note that 21871 * // this can also be done with the language.thousands option) 21872 * $(document).ready( function() { 21873 * $('#example').dataTable( { 21874 * "formatNumber": function ( toFormat ) { 21875 * return toFormat.toString().replace( 21876 * /\B(?=(\d{3})+(?!\d))/g, "'" 21877 * ); 21878 * }; 21879 * } ); 21880 * } ); 21881 */ 21882 "fnFormatNumber": function ( toFormat ) { 21883 return toFormat.toString().replace( 21884 /\B(?=(\d{3})+(?!\d))/g, 21885 this.oLanguage.sThousands 21886 ); 21887 }, 21888 21889 21890 /** 21891 * This function is called on every 'draw' event, and allows you to 21892 * dynamically modify the header row. This can be used to calculate and 21893 * display useful information about the table. 21894 * @type function 21895 * @param {node} head "TR" element for the header 21896 * @param {array} data Full table data (as derived from the original HTML) 21897 * @param {int} start Index for the current display starting point in the 21898 * display array 21899 * @param {int} end Index for the current display ending point in the 21900 * display array 21901 * @param {array int} display Index array to translate the visual position 21902 * to the full data array 21903 * 21904 * @dtopt Callbacks 21905 * @name DataTable.defaults.headerCallback 21906 * 21907 * @example 21908 * $(document).ready( function() { 21909 * $('#example').dataTable( { 21910 * "fheaderCallback": function( head, data, start, end, display ) { 21911 * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records"; 21912 * } 21913 * } ); 21914 * } ) 21915 */ 21916 "fnHeaderCallback": null, 21917 21918 21919 /** 21920 * The information element can be used to convey information about the current 21921 * state of the table. Although the internationalisation options presented by 21922 * DataTables are quite capable of dealing with most customisations, there may 21923 * be times where you wish to customise the string further. This callback 21924 * allows you to do exactly that. 21925 * @type function 21926 * @param {object} oSettings DataTables settings object 21927 * @param {int} start Starting position in data for the draw 21928 * @param {int} end End position in data for the draw 21929 * @param {int} max Total number of rows in the table (regardless of 21930 * filtering) 21931 * @param {int} total Total number of rows in the data set, after filtering 21932 * @param {string} pre The string that DataTables has formatted using it's 21933 * own rules 21934 * @returns {string} The string to be displayed in the information element. 21935 * 21936 * @dtopt Callbacks 21937 * @name DataTable.defaults.infoCallback 21938 * 21939 * @example 21940 * $('#example').dataTable( { 21941 * "infoCallback": function( settings, start, end, max, total, pre ) { 21942 * return start +" to "+ end; 21943 * } 21944 * } ); 21945 */ 21946 "fnInfoCallback": null, 21947 21948 21949 /** 21950 * Called when the table has been initialised. Normally DataTables will 21951 * initialise sequentially and there will be no need for this function, 21952 * however, this does not hold true when using external language information 21953 * since that is obtained using an async XHR call. 21954 * @type function 21955 * @param {object} settings DataTables settings object 21956 * @param {object} json The JSON object request from the server - only 21957 * present if client-side Ajax sourced data is used 21958 * 21959 * @dtopt Callbacks 21960 * @name DataTable.defaults.initComplete 21961 * 21962 * @example 21963 * $(document).ready( function() { 21964 * $('#example').dataTable( { 21965 * "initComplete": function(settings, json) { 21966 * alert( 'DataTables has finished its initialisation.' ); 21967 * } 21968 * } ); 21969 * } ) 21970 */ 21971 "fnInitComplete": null, 21972 21973 21974 /** 21975 * Called at the very start of each table draw and can be used to cancel the 21976 * draw by returning false, any other return (including undefined) results in 21977 * the full draw occurring). 21978 * @type function 21979 * @param {object} settings DataTables settings object 21980 * @returns {boolean} False will cancel the draw, anything else (including no 21981 * return) will allow it to complete. 21982 * 21983 * @dtopt Callbacks 21984 * @name DataTable.defaults.preDrawCallback 21985 * 21986 * @example 21987 * $(document).ready( function() { 21988 * $('#example').dataTable( { 21989 * "preDrawCallback": function( settings ) { 21990 * if ( $('#test').val() == 1 ) { 21991 * return false; 21992 * } 21993 * } 21994 * } ); 21995 * } ); 21996 */ 21997 "fnPreDrawCallback": null, 21998 21999 22000 /** 22001 * This function allows you to 'post process' each row after it have been 22002 * generated for each table draw, but before it is rendered on screen. This 22003 * function might be used for setting the row class name etc. 22004 * @type function 22005 * @param {node} row "TR" element for the current row 22006 * @param {array} data Raw data array for this row 22007 * @param {int} displayIndex The display index for the current table draw 22008 * @param {int} displayIndexFull The index of the data in the full list of 22009 * rows (after filtering) 22010 * 22011 * @dtopt Callbacks 22012 * @name DataTable.defaults.rowCallback 22013 * 22014 * @example 22015 * $(document).ready( function() { 22016 * $('#example').dataTable( { 22017 * "rowCallback": function( row, data, displayIndex, displayIndexFull ) { 22018 * // Bold the grade for all 'A' grade browsers 22019 * if ( data[4] == "A" ) { 22020 * $('td:eq(4)', row).html( '<b>A</b>' ); 22021 * } 22022 * } 22023 * } ); 22024 * } ); 22025 */ 22026 "fnRowCallback": null, 22027 22028 22029 /** 22030 * __Deprecated__ The functionality provided by this parameter has now been 22031 * superseded by that provided through `ajax`, which should be used instead. 22032 * 22033 * This parameter allows you to override the default function which obtains 22034 * the data from the server so something more suitable for your application. 22035 * For example you could use POST data, or pull information from a Gears or 22036 * AIR database. 22037 * @type function 22038 * @member 22039 * @param {string} source HTTP source to obtain the data from (`ajax`) 22040 * @param {array} data A key/value pair object containing the data to send 22041 * to the server 22042 * @param {function} callback to be called on completion of the data get 22043 * process that will draw the data on the page. 22044 * @param {object} settings DataTables settings object 22045 * 22046 * @dtopt Callbacks 22047 * @dtopt Server-side 22048 * @name DataTable.defaults.serverData 22049 * 22050 * @deprecated 1.10. Please use `ajax` for this functionality now. 22051 */ 22052 "fnServerData": null, 22053 22054 22055 /** 22056 * __Deprecated__ The functionality provided by this parameter has now been 22057 * superseded by that provided through `ajax`, which should be used instead. 22058 * 22059 * It is often useful to send extra data to the server when making an Ajax 22060 * request - for example custom filtering information, and this callback 22061 * function makes it trivial to send extra information to the server. The 22062 * passed in parameter is the data set that has been constructed by 22063 * DataTables, and you can add to this or modify it as you require. 22064 * @type function 22065 * @param {array} data Data array (array of objects which are name/value 22066 * pairs) that has been constructed by DataTables and will be sent to the 22067 * server. In the case of Ajax sourced data with server-side processing 22068 * this will be an empty array, for server-side processing there will be a 22069 * significant number of parameters! 22070 * @returns {undefined} Ensure that you modify the data array passed in, 22071 * as this is passed by reference. 22072 * 22073 * @dtopt Callbacks 22074 * @dtopt Server-side 22075 * @name DataTable.defaults.serverParams 22076 * 22077 * @deprecated 1.10. Please use `ajax` for this functionality now. 22078 */ 22079 "fnServerParams": null, 22080 22081 22082 /** 22083 * Load the table state. With this function you can define from where, and how, the 22084 * state of a table is loaded. By default DataTables will load from `localStorage` 22085 * but you might wish to use a server-side database or cookies. 22086 * @type function 22087 * @member 22088 * @param {object} settings DataTables settings object 22089 * @param {object} callback Callback that can be executed when done. It 22090 * should be passed the loaded state object. 22091 * @return {object} The DataTables state object to be loaded 22092 * 22093 * @dtopt Callbacks 22094 * @name DataTable.defaults.stateLoadCallback 22095 * 22096 * @example 22097 * $(document).ready( function() { 22098 * $('#example').dataTable( { 22099 * "stateSave": true, 22100 * "stateLoadCallback": function (settings, callback) { 22101 * $.ajax( { 22102 * "url": "/state_load", 22103 * "dataType": "json", 22104 * "success": function (json) { 22105 * callback( json ); 22106 * } 22107 * } ); 22108 * } 22109 * } ); 22110 * } ); 22111 */ 22112 "fnStateLoadCallback": function ( settings ) { 22113 try { 22114 return JSON.parse( 22115 (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem( 22116 'DataTables_'+settings.sInstance+'_'+location.pathname 22117 ) 22118 ); 22119 } catch (e) { 22120 return {}; 22121 } 22122 }, 22123 22124 22125 /** 22126 * Callback which allows modification of the saved state prior to loading that state. 22127 * This callback is called when the table is loading state from the stored data, but 22128 * prior to the settings object being modified by the saved state. Note that for 22129 * plug-in authors, you should use the `stateLoadParams` event to load parameters for 22130 * a plug-in. 22131 * @type function 22132 * @param {object} settings DataTables settings object 22133 * @param {object} data The state object that is to be loaded 22134 * 22135 * @dtopt Callbacks 22136 * @name DataTable.defaults.stateLoadParams 22137 * 22138 * @example 22139 * // Remove a saved filter, so filtering is never loaded 22140 * $(document).ready( function() { 22141 * $('#example').dataTable( { 22142 * "stateSave": true, 22143 * "stateLoadParams": function (settings, data) { 22144 * data.oSearch.sSearch = ""; 22145 * } 22146 * } ); 22147 * } ); 22148 * 22149 * @example 22150 * // Disallow state loading by returning false 22151 * $(document).ready( function() { 22152 * $('#example').dataTable( { 22153 * "stateSave": true, 22154 * "stateLoadParams": function (settings, data) { 22155 * return false; 22156 * } 22157 * } ); 22158 * } ); 22159 */ 22160 "fnStateLoadParams": null, 22161 22162 22163 /** 22164 * Callback that is called when the state has been loaded from the state saving method 22165 * and the DataTables settings object has been modified as a result of the loaded state. 22166 * @type function 22167 * @param {object} settings DataTables settings object 22168 * @param {object} data The state object that was loaded 22169 * 22170 * @dtopt Callbacks 22171 * @name DataTable.defaults.stateLoaded 22172 * 22173 * @example 22174 * // Show an alert with the filtering value that was saved 22175 * $(document).ready( function() { 22176 * $('#example').dataTable( { 22177 * "stateSave": true, 22178 * "stateLoaded": function (settings, data) { 22179 * alert( 'Saved filter was: '+data.oSearch.sSearch ); 22180 * } 22181 * } ); 22182 * } ); 22183 */ 22184 "fnStateLoaded": null, 22185 22186 22187 /** 22188 * Save the table state. This function allows you to define where and how the state 22189 * information for the table is stored By default DataTables will use `localStorage` 22190 * but you might wish to use a server-side database or cookies. 22191 * @type function 22192 * @member 22193 * @param {object} settings DataTables settings object 22194 * @param {object} data The state object to be saved 22195 * 22196 * @dtopt Callbacks 22197 * @name DataTable.defaults.stateSaveCallback 22198 * 22199 * @example 22200 * $(document).ready( function() { 22201 * $('#example').dataTable( { 22202 * "stateSave": true, 22203 * "stateSaveCallback": function (settings, data) { 22204 * // Send an Ajax request to the server with the state object 22205 * $.ajax( { 22206 * "url": "/state_save", 22207 * "data": data, 22208 * "dataType": "json", 22209 * "method": "POST" 22210 * "success": function () {} 22211 * } ); 22212 * } 22213 * } ); 22214 * } ); 22215 */ 22216 "fnStateSaveCallback": function ( settings, data ) { 22217 try { 22218 (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem( 22219 'DataTables_'+settings.sInstance+'_'+location.pathname, 22220 JSON.stringify( data ) 22221 ); 22222 } catch (e) {} 22223 }, 22224 22225 22226 /** 22227 * Callback which allows modification of the state to be saved. Called when the table 22228 * has changed state a new state save is required. This method allows modification of 22229 * the state saving object prior to actually doing the save, including addition or 22230 * other state properties or modification. Note that for plug-in authors, you should 22231 * use the `stateSaveParams` event to save parameters for a plug-in. 22232 * @type function 22233 * @param {object} settings DataTables settings object 22234 * @param {object} data The state object to be saved 22235 * 22236 * @dtopt Callbacks 22237 * @name DataTable.defaults.stateSaveParams 22238 * 22239 * @example 22240 * // Remove a saved filter, so filtering is never saved 22241 * $(document).ready( function() { 22242 * $('#example').dataTable( { 22243 * "stateSave": true, 22244 * "stateSaveParams": function (settings, data) { 22245 * data.oSearch.sSearch = ""; 22246 * } 22247 * } ); 22248 * } ); 22249 */ 22250 "fnStateSaveParams": null, 22251 22252 22253 /** 22254 * Duration for which the saved state information is considered valid. After this period 22255 * has elapsed the state will be returned to the default. 22256 * Value is given in seconds. 22257 * @type int 22258 * @default 7200 <i>(2 hours)</i> 22259 * 22260 * @dtopt Options 22261 * @name DataTable.defaults.stateDuration 22262 * 22263 * @example 22264 * $(document).ready( function() { 22265 * $('#example').dataTable( { 22266 * "stateDuration": 60*60*24; // 1 day 22267 * } ); 22268 * } ) 22269 */ 22270 "iStateDuration": 7200, 22271 22272 22273 /** 22274 * When enabled DataTables will not make a request to the server for the first 22275 * page draw - rather it will use the data already on the page (no sorting etc 22276 * will be applied to it), thus saving on an XHR at load time. `deferLoading` 22277 * is used to indicate that deferred loading is required, but it is also used 22278 * to tell DataTables how many records there are in the full table (allowing 22279 * the information element and pagination to be displayed correctly). In the case 22280 * where a filtering is applied to the table on initial load, this can be 22281 * indicated by giving the parameter as an array, where the first element is 22282 * the number of records available after filtering and the second element is the 22283 * number of records without filtering (allowing the table information element 22284 * to be shown correctly). 22285 * @type int | array 22286 * @default null 22287 * 22288 * @dtopt Options 22289 * @name DataTable.defaults.deferLoading 22290 * 22291 * @example 22292 * // 57 records available in the table, no filtering applied 22293 * $(document).ready( function() { 22294 * $('#example').dataTable( { 22295 * "serverSide": true, 22296 * "ajax": "scripts/server_processing.php", 22297 * "deferLoading": 57 22298 * } ); 22299 * } ); 22300 * 22301 * @example 22302 * // 57 records after filtering, 100 without filtering (an initial filter applied) 22303 * $(document).ready( function() { 22304 * $('#example').dataTable( { 22305 * "serverSide": true, 22306 * "ajax": "scripts/server_processing.php", 22307 * "deferLoading": [ 57, 100 ], 22308 * "search": { 22309 * "search": "my_filter" 22310 * } 22311 * } ); 22312 * } ); 22313 */ 22314 "iDeferLoading": null, 22315 22316 22317 /** 22318 * Number of rows to display on a single page when using pagination. If 22319 * feature enabled (`lengthChange`) then the end user will be able to override 22320 * this to a custom setting using a pop-up menu. 22321 * @type int 22322 * @default 10 22323 * 22324 * @dtopt Options 22325 * @name DataTable.defaults.pageLength 22326 * 22327 * @example 22328 * $(document).ready( function() { 22329 * $('#example').dataTable( { 22330 * "pageLength": 50 22331 * } ); 22332 * } ) 22333 */ 22334 "iDisplayLength": 10, 22335 22336 22337 /** 22338 * Define the starting point for data display when using DataTables with 22339 * pagination. Note that this parameter is the number of records, rather than 22340 * the page number, so if you have 10 records per page and want to start on 22341 * the third page, it should be "20". 22342 * @type int 22343 * @default 0 22344 * 22345 * @dtopt Options 22346 * @name DataTable.defaults.displayStart 22347 * 22348 * @example 22349 * $(document).ready( function() { 22350 * $('#example').dataTable( { 22351 * "displayStart": 20 22352 * } ); 22353 * } ) 22354 */ 22355 "iDisplayStart": 0, 22356 22357 22358 /** 22359 * By default DataTables allows keyboard navigation of the table (sorting, paging, 22360 * and filtering) by adding a `tabindex` attribute to the required elements. This 22361 * allows you to tab through the controls and press the enter key to activate them. 22362 * The tabindex is default 0, meaning that the tab follows the flow of the document. 22363 * You can overrule this using this parameter if you wish. Use a value of -1 to 22364 * disable built-in keyboard navigation. 22365 * @type int 22366 * @default 0 22367 * 22368 * @dtopt Options 22369 * @name DataTable.defaults.tabIndex 22370 * 22371 * @example 22372 * $(document).ready( function() { 22373 * $('#example').dataTable( { 22374 * "tabIndex": 1 22375 * } ); 22376 * } ); 22377 */ 22378 "iTabIndex": 0, 22379 22380 22381 /** 22382 * Classes that DataTables assigns to the various components and features 22383 * that it adds to the HTML table. This allows classes to be configured 22384 * during initialisation in addition to through the static 22385 * {@link DataTable.ext.oStdClasses} object). 22386 * @namespace 22387 * @name DataTable.defaults.classes 22388 */ 22389 "oClasses": {}, 22390 22391 22392 /** 22393 * All strings that DataTables uses in the user interface that it creates 22394 * are defined in this object, allowing you to modified them individually or 22395 * completely replace them all as required. 22396 * @namespace 22397 * @name DataTable.defaults.language 22398 */ 22399 "oLanguage": { 22400 /** 22401 * Strings that are used for WAI-ARIA labels and controls only (these are not 22402 * actually visible on the page, but will be read by screenreaders, and thus 22403 * must be internationalised as well). 22404 * @namespace 22405 * @name DataTable.defaults.language.aria 22406 */ 22407 "oAria": { 22408 /** 22409 * ARIA label that is added to the table headers when the column may be 22410 * sorted ascending by activing the column (click or return when focused). 22411 * Note that the column header is prefixed to this string. 22412 * @type string 22413 * @default : activate to sort column ascending 22414 * 22415 * @dtopt Language 22416 * @name DataTable.defaults.language.aria.sortAscending 22417 * 22418 * @example 22419 * $(document).ready( function() { 22420 * $('#example').dataTable( { 22421 * "language": { 22422 * "aria": { 22423 * "sortAscending": " - click/return to sort ascending" 22424 * } 22425 * } 22426 * } ); 22427 * } ); 22428 */ 22429 "sSortAscending": ": activate to sort column ascending", 22430 22431 /** 22432 * ARIA label that is added to the table headers when the column may be 22433 * sorted descending by activing the column (click or return when focused). 22434 * Note that the column header is prefixed to this string. 22435 * @type string 22436 * @default : activate to sort column ascending 22437 * 22438 * @dtopt Language 22439 * @name DataTable.defaults.language.aria.sortDescending 22440 * 22441 * @example 22442 * $(document).ready( function() { 22443 * $('#example').dataTable( { 22444 * "language": { 22445 * "aria": { 22446 * "sortDescending": " - click/return to sort descending" 22447 * } 22448 * } 22449 * } ); 22450 * } ); 22451 */ 22452 "sSortDescending": ": activate to sort column descending" 22453 }, 22454 22455 /** 22456 * Pagination string used by DataTables for the built-in pagination 22457 * control types. 22458 * @namespace 22459 * @name DataTable.defaults.language.paginate 22460 */ 22461 "oPaginate": { 22462 /** 22463 * Text to use when using the 'full_numbers' type of pagination for the 22464 * button to take the user to the first page. 22465 * @type string 22466 * @default First 22467 * 22468 * @dtopt Language 22469 * @name DataTable.defaults.language.paginate.first 22470 * 22471 * @example 22472 * $(document).ready( function() { 22473 * $('#example').dataTable( { 22474 * "language": { 22475 * "paginate": { 22476 * "first": "First page" 22477 * } 22478 * } 22479 * } ); 22480 * } ); 22481 */ 22482 "sFirst": "First", 22483 22484 22485 /** 22486 * Text to use when using the 'full_numbers' type of pagination for the 22487 * button to take the user to the last page. 22488 * @type string 22489 * @default Last 22490 * 22491 * @dtopt Language 22492 * @name DataTable.defaults.language.paginate.last 22493 * 22494 * @example 22495 * $(document).ready( function() { 22496 * $('#example').dataTable( { 22497 * "language": { 22498 * "paginate": { 22499 * "last": "Last page" 22500 * } 22501 * } 22502 * } ); 22503 * } ); 22504 */ 22505 "sLast": "Last", 22506 22507 22508 /** 22509 * Text to use for the 'next' pagination button (to take the user to the 22510 * next page). 22511 * @type string 22512 * @default Next 22513 * 22514 * @dtopt Language 22515 * @name DataTable.defaults.language.paginate.next 22516 * 22517 * @example 22518 * $(document).ready( function() { 22519 * $('#example').dataTable( { 22520 * "language": { 22521 * "paginate": { 22522 * "next": "Next page" 22523 * } 22524 * } 22525 * } ); 22526 * } ); 22527 */ 22528 "sNext": "Next", 22529 22530 22531 /** 22532 * Text to use for the 'previous' pagination button (to take the user to 22533 * the previous page). 22534 * @type string 22535 * @default Previous 22536 * 22537 * @dtopt Language 22538 * @name DataTable.defaults.language.paginate.previous 22539 * 22540 * @example 22541 * $(document).ready( function() { 22542 * $('#example').dataTable( { 22543 * "language": { 22544 * "paginate": { 22545 * "previous": "Previous page" 22546 * } 22547 * } 22548 * } ); 22549 * } ); 22550 */ 22551 "sPrevious": "Previous" 22552 }, 22553 22554 /** 22555 * This string is shown in preference to `zeroRecords` when the table is 22556 * empty of data (regardless of filtering). Note that this is an optional 22557 * parameter - if it is not given, the value of `zeroRecords` will be used 22558 * instead (either the default or given value). 22559 * @type string 22560 * @default No data available in table 22561 * 22562 * @dtopt Language 22563 * @name DataTable.defaults.language.emptyTable 22564 * 22565 * @example 22566 * $(document).ready( function() { 22567 * $('#example').dataTable( { 22568 * "language": { 22569 * "emptyTable": "No data available in table" 22570 * } 22571 * } ); 22572 * } ); 22573 */ 22574 "sEmptyTable": "No data available in table", 22575 22576 22577 /** 22578 * This string gives information to the end user about the information 22579 * that is current on display on the page. The following tokens can be 22580 * used in the string and will be dynamically replaced as the table 22581 * display updates. This tokens can be placed anywhere in the string, or 22582 * removed as needed by the language requires: 22583 * 22584 * * `\_START\_` - Display index of the first record on the current page 22585 * * `\_END\_` - Display index of the last record on the current page 22586 * * `\_TOTAL\_` - Number of records in the table after filtering 22587 * * `\_MAX\_` - Number of records in the table without filtering 22588 * * `\_PAGE\_` - Current page number 22589 * * `\_PAGES\_` - Total number of pages of data in the table 22590 * 22591 * @type string 22592 * @default Showing _START_ to _END_ of _TOTAL_ entries 22593 * 22594 * @dtopt Language 22595 * @name DataTable.defaults.language.info 22596 * 22597 * @example 22598 * $(document).ready( function() { 22599 * $('#example').dataTable( { 22600 * "language": { 22601 * "info": "Showing page _PAGE_ of _PAGES_" 22602 * } 22603 * } ); 22604 * } ); 22605 */ 22606 "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", 22607 22608 22609 /** 22610 * Display information string for when the table is empty. Typically the 22611 * format of this string should match `info`. 22612 * @type string 22613 * @default Showing 0 to 0 of 0 entries 22614 * 22615 * @dtopt Language 22616 * @name DataTable.defaults.language.infoEmpty 22617 * 22618 * @example 22619 * $(document).ready( function() { 22620 * $('#example').dataTable( { 22621 * "language": { 22622 * "infoEmpty": "No entries to show" 22623 * } 22624 * } ); 22625 * } ); 22626 */ 22627 "sInfoEmpty": "Showing 0 to 0 of 0 entries", 22628 22629 22630 /** 22631 * When a user filters the information in a table, this string is appended 22632 * to the information (`info`) to give an idea of how strong the filtering 22633 * is. The variable _MAX_ is dynamically updated. 22634 * @type string 22635 * @default (filtered from _MAX_ total entries) 22636 * 22637 * @dtopt Language 22638 * @name DataTable.defaults.language.infoFiltered 22639 * 22640 * @example 22641 * $(document).ready( function() { 22642 * $('#example').dataTable( { 22643 * "language": { 22644 * "infoFiltered": " - filtering from _MAX_ records" 22645 * } 22646 * } ); 22647 * } ); 22648 */ 22649 "sInfoFiltered": "(filtered from _MAX_ total entries)", 22650 22651 22652 /** 22653 * If can be useful to append extra information to the info string at times, 22654 * and this variable does exactly that. This information will be appended to 22655 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are 22656 * being used) at all times. 22657 * @type string 22658 * @default <i>Empty string</i> 22659 * 22660 * @dtopt Language 22661 * @name DataTable.defaults.language.infoPostFix 22662 * 22663 * @example 22664 * $(document).ready( function() { 22665 * $('#example').dataTable( { 22666 * "language": { 22667 * "infoPostFix": "All records shown are derived from real information." 22668 * } 22669 * } ); 22670 * } ); 22671 */ 22672 "sInfoPostFix": "", 22673 22674 22675 /** 22676 * This decimal place operator is a little different from the other 22677 * language options since DataTables doesn't output floating point 22678 * numbers, so it won't ever use this for display of a number. Rather, 22679 * what this parameter does is modify the sort methods of the table so 22680 * that numbers which are in a format which has a character other than 22681 * a period (`.`) as a decimal place will be sorted numerically. 22682 * 22683 * Note that numbers with different decimal places cannot be shown in 22684 * the same table and still be sortable, the table must be consistent. 22685 * However, multiple different tables on the page can use different 22686 * decimal place characters. 22687 * @type string 22688 * @default 22689 * 22690 * @dtopt Language 22691 * @name DataTable.defaults.language.decimal 22692 * 22693 * @example 22694 * $(document).ready( function() { 22695 * $('#example').dataTable( { 22696 * "language": { 22697 * "decimal": "," 22698 * "thousands": "." 22699 * } 22700 * } ); 22701 * } ); 22702 */ 22703 "sDecimal": "", 22704 22705 22706 /** 22707 * DataTables has a build in number formatter (`formatNumber`) which is 22708 * used to format large numbers that are used in the table information. 22709 * By default a comma is used, but this can be trivially changed to any 22710 * character you wish with this parameter. 22711 * @type string 22712 * @default , 22713 * 22714 * @dtopt Language 22715 * @name DataTable.defaults.language.thousands 22716 * 22717 * @example 22718 * $(document).ready( function() { 22719 * $('#example').dataTable( { 22720 * "language": { 22721 * "thousands": "'" 22722 * } 22723 * } ); 22724 * } ); 22725 */ 22726 "sThousands": ",", 22727 22728 22729 /** 22730 * Detail the action that will be taken when the drop down menu for the 22731 * pagination length option is changed. The '_MENU_' variable is replaced 22732 * with a default select list of 10, 25, 50 and 100, and can be replaced 22733 * with a custom select box if required. 22734 * @type string 22735 * @default Show _MENU_ entries 22736 * 22737 * @dtopt Language 22738 * @name DataTable.defaults.language.lengthMenu 22739 * 22740 * @example 22741 * // Language change only 22742 * $(document).ready( function() { 22743 * $('#example').dataTable( { 22744 * "language": { 22745 * "lengthMenu": "Display _MENU_ records" 22746 * } 22747 * } ); 22748 * } ); 22749 * 22750 * @example 22751 * // Language and options change 22752 * $(document).ready( function() { 22753 * $('#example').dataTable( { 22754 * "language": { 22755 * "lengthMenu": 'Display <select>'+ 22756 * '<option value="10">10</option>'+ 22757 * '<option value="20">20</option>'+ 22758 * '<option value="30">30</option>'+ 22759 * '<option value="40">40</option>'+ 22760 * '<option value="50">50</option>'+ 22761 * '<option value="-1">All</option>'+ 22762 * '</select> records' 22763 * } 22764 * } ); 22765 * } ); 22766 */ 22767 "sLengthMenu": "Show _MENU_ entries", 22768 22769 22770 /** 22771 * When using Ajax sourced data and during the first draw when DataTables is 22772 * gathering the data, this message is shown in an empty row in the table to 22773 * indicate to the end user the the data is being loaded. Note that this 22774 * parameter is not used when loading data by server-side processing, just 22775 * Ajax sourced data with client-side processing. 22776 * @type string 22777 * @default Loading... 22778 * 22779 * @dtopt Language 22780 * @name DataTable.defaults.language.loadingRecords 22781 * 22782 * @example 22783 * $(document).ready( function() { 22784 * $('#example').dataTable( { 22785 * "language": { 22786 * "loadingRecords": "Please wait - loading..." 22787 * } 22788 * } ); 22789 * } ); 22790 */ 22791 "sLoadingRecords": "Loading...", 22792 22793 22794 /** 22795 * Text which is displayed when the table is processing a user action 22796 * (usually a sort command or similar). 22797 * @type string 22798 *
22798 @default Processing... 22799 * 22800 * @dtopt Language 22801 * @name DataTable.defaults.language.processing 22802 * 22803 * @example 22804 * $(document).ready( function() { 22805 * $('#example').dataTable( { 22806 * "language": { 22807 * "processing": "DataTables is currently busy" 22808 * } 22809 * } ); 22810 * } ); 22811 */ 22812 "sProcessing": "Processing...
vendor: 85,392 bytes, lines 22812-25656
22812", 22813 22814 22815 /** 22816 * Details the actions that will be taken when the user types into the 22817 * filtering input text box. The variable "_INPUT_", if used in the string, 22818 * is replaced with the HTML text box for the filtering input allowing 22819 * control over where it appears in the string. If "_INPUT_" is not given 22820 * then the input box is appended to the string automatically. 22821 * @type string 22822 * @default Search: 22823 * 22824 * @dtopt Language 22825 * @name DataTable.defaults.language.search 22826 * 22827 * @example 22828 * // Input text box will be appended at the end automatically 22829 * $(document).ready( function() { 22830 * $('#example').dataTable( { 22831 * "language": { 22832 * "search": "Filter records:" 22833 * } 22834 * } ); 22835 * } ); 22836 * 22837 * @example 22838 * // Specify where the filter should appear 22839 * $(document).ready( function() { 22840 * $('#example').dataTable( { 22841 * "language": { 22842 * "search": "Apply filter _INPUT_ to table" 22843 * } 22844 * } ); 22845 * } ); 22846 */ 22847 "sSearch": "Search:", 22848 22849 22850 /** 22851 * Assign a `placeholder` attribute to the search `input` element 22852 * @type string 22853 * @default 22854 * 22855 * @dtopt Language 22856 * @name DataTable.defaults.language.searchPlaceholder 22857 */ 22858 "sSearchPlaceholder": "", 22859 22860 22861 /** 22862 * All of the language information can be stored in a file on the 22863 * server-side, which DataTables will look up if this parameter is passed. 22864 * It must store the URL of the language file, which is in a JSON format, 22865 * and the object has the same properties as the oLanguage object in the 22866 * initialiser object (i.e. the above parameters). Please refer to one of 22867 * the example language files to see how this works in action. 22868 * @type string 22869 * @default <i>Empty string - i.e. disabled</i> 22870 * 22871 * @dtopt Language 22872 * @name DataTable.defaults.language.url 22873 * 22874 * @example 22875 * $(document).ready( function() { 22876 * $('#example').dataTable( { 22877 * "language": { 22878 * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt" 22879 * } 22880 * } ); 22881 * } ); 22882 */ 22883 "sUrl": "", 22884 22885 22886 /** 22887 * Text shown inside the table records when the is no information to be 22888 * displayed after filtering. `emptyTable` is shown when there is simply no 22889 * information in the table at all (regardless of filtering). 22890 * @type string 22891 * @default No matching records found 22892 * 22893 * @dtopt Language 22894 * @name DataTable.defaults.language.zeroRecords 22895 * 22896 * @example 22897 * $(document).ready( function() { 22898 * $('#example').dataTable( { 22899 * "language": { 22900 * "zeroRecords": "No records to display" 22901 * } 22902 * } ); 22903 * } ); 22904 */ 22905 "sZeroRecords": "No matching records found" 22906 }, 22907 22908 22909 /** 22910 * This parameter allows you to have define the global filtering state at 22911 * initialisation time. As an object the `search` parameter must be 22912 * defined, but all other parameters are optional. When `regex` is true, 22913 * the search string will be treated as a regular expression, when false 22914 * (default) it will be treated as a straight string. When `smart` 22915 * DataTables will use it's smart filtering methods (to word match at 22916 * any point in the data), when false this will not be done. 22917 * @namespace 22918 * @extends DataTable.models.oSearch 22919 * 22920 * @dtopt Options 22921 * @name DataTable.defaults.search 22922 * 22923 * @example 22924 * $(document).ready( function() { 22925 * $('#example').dataTable( { 22926 * "search": {"search": "Initial search"} 22927 * } ); 22928 * } ) 22929 */ 22930 "oSearch": $.extend( {}, DataTable.models.oSearch ), 22931 22932 22933 /** 22934 * __Deprecated__ The functionality provided by this parameter has now been 22935 * superseded by that provided through `ajax`, which should be used instead. 22936 * 22937 * By default DataTables will look for the property `data` (or `aaData` for 22938 * compatibility with DataTables 1.9-) when obtaining data from an Ajax 22939 * source or for server-side processing - this parameter allows that 22940 * property to be changed. You can use Javascript dotted object notation to 22941 * get a data source for multiple levels of nesting. 22942 * @type string 22943 * @default data 22944 * 22945 * @dtopt Options 22946 * @dtopt Server-side 22947 * @name DataTable.defaults.ajaxDataProp 22948 * 22949 * @deprecated 1.10. Please use `ajax` for this functionality now. 22950 */ 22951 "sAjaxDataProp": "data", 22952 22953 22954 /** 22955 * __Deprecated__ The functionality provided by this parameter has now been 22956 * superseded by that provided through `ajax`, which should be used instead. 22957 * 22958 * You can instruct DataTables to load data from an external 22959 * source using this parameter (use aData if you want to pass data in you 22960 * already have). Simply provide a url a JSON object can be obtained from. 22961 * @type string 22962 * @default null 22963 * 22964 * @dtopt Options 22965 * @dtopt Server-side 22966 * @name DataTable.defaults.ajaxSource 22967 * 22968 * @deprecated 1.10. Please use `ajax` for this functionality now. 22969 */ 22970 "sAjaxSource": null, 22971 22972 22973 /** 22974 * This initialisation variable allows you to specify exactly where in the 22975 * DOM you want DataTables to inject the various controls it adds to the page 22976 * (for example you might want the pagination controls at the top of the 22977 * table). DIV elements (with or without a custom class) can also be added to 22978 * aid styling. The follow syntax is used: 22979 * <ul> 22980 * <li>The following options are allowed: 22981 * <ul> 22982 * <li>'l' - Length changing</li> 22983 * <li>'f' - Filtering input</li> 22984 * <li>'t' - The table!</li> 22985 * <li>'i' - Information</li> 22986 * <li>'p' - Pagination</li> 22987 * <li>'r' - pRocessing</li> 22988 * </ul> 22989 * </li> 22990 * <li>The following constants are allowed: 22991 * <ul> 22992 * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li> 22993 * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li> 22994 * </ul> 22995 * </li> 22996 * <li>The following syntax is expected: 22997 * <ul> 22998 * <li>'<' and '>' - div elements</li> 22999 * <li>'<"class" and '>' - div with a class</li> 23000 * <li>'<"#id" and '>' - div with an ID</li> 23001 * </ul> 23002 * </li> 23003 * <li>Examples: 23004 * <ul> 23005 * <li>'<"wrapper"flipt>'</li> 23006 * <li>'<lf<t>ip>'</li> 23007 * </ul> 23008 * </li> 23009 * </ul> 23010 * @type string 23011 * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b> 23012 * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i> 23013 * 23014 * @dtopt Options 23015 * @name DataTable.defaults.dom 23016 * 23017 * @example 23018 * $(document).ready( function() { 23019 * $('#example').dataTable( { 23020 * "dom": '<"top"i>rt<"bottom"flp><"clear">' 23021 * } ); 23022 * } ); 23023 */ 23024 "sDom": "lfrtip", 23025 23026 23027 /** 23028 * Search delay option. This will throttle full table searches that use the 23029 * DataTables provided search input element (it does not effect calls to 23030 * `dt-api search()`, providing a delay before the search is made. 23031 * @type integer 23032 * @default 0 23033 * 23034 * @dtopt Options 23035 * @name DataTable.defaults.searchDelay 23036 * 23037 * @example 23038 * $(document).ready( function() { 23039 * $('#example').dataTable( { 23040 * "searchDelay": 200 23041 * } ); 23042 * } ) 23043 */ 23044 "searchDelay": null, 23045 23046 23047 /** 23048 * DataTables features six different built-in options for the buttons to 23049 * display for pagination control: 23050 * 23051 * * `numbers` - Page number buttons only 23052 * * `simple` - 'Previous' and 'Next' buttons only 23053 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers 23054 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons 23055 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers 23056 * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers 23057 * 23058 * Further methods can be added using {@link DataTable.ext.oPagination}. 23059 * @type string 23060 * @default simple_numbers 23061 * 23062 * @dtopt Options 23063 * @name DataTable.defaults.pagingType 23064 * 23065 * @example 23066 * $(document).ready( function() { 23067 * $('#example').dataTable( { 23068 * "pagingType": "full_numbers" 23069 * } ); 23070 * } ) 23071 */ 23072 "sPaginationType": "simple_numbers", 23073 23074 23075 /** 23076 * Enable horizontal scrolling. When a table is too wide to fit into a 23077 * certain layout, or you have a large number of columns in the table, you 23078 * can enable x-scrolling to show the table in a viewport, which can be 23079 * scrolled. This property can be `true` which will allow the table to 23080 * scroll horizontally when needed, or any CSS unit, or a number (in which 23081 * case it will be treated as a pixel measurement). Setting as simply `true` 23082 * is recommended. 23083 * @type boolean|string 23084 * @default <i>blank string - i.e. disabled</i> 23085 * 23086 * @dtopt Features 23087 * @name DataTable.defaults.scrollX 23088 * 23089 * @example 23090 * $(document).ready( function() { 23091 * $('#example').dataTable( { 23092 * "scrollX": true, 23093 * "scrollCollapse": true 23094 * } ); 23095 * } ); 23096 */ 23097 "sScrollX": "", 23098 23099 23100 /** 23101 * This property can be used to force a DataTable to use more width than it 23102 * might otherwise do when x-scrolling is enabled. For example if you have a 23103 * table which requires to be well spaced, this parameter is useful for 23104 * "over-sizing" the table, and thus forcing scrolling. This property can by 23105 * any CSS unit, or a number (in which case it will be treated as a pixel 23106 * measurement). 23107 * @type string 23108 * @default <i>blank string - i.e. disabled</i> 23109 * 23110 * @dtopt Options 23111 * @name DataTable.defaults.scrollXInner 23112 * 23113 * @example 23114 * $(document).ready( function() { 23115 * $('#example').dataTable( { 23116 * "scrollX": "100%", 23117 * "scrollXInner": "110%" 23118 * } ); 23119 * } ); 23120 */ 23121 "sScrollXInner": "", 23122 23123 23124 /** 23125 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable 23126 * to the given height, and enable scrolling for any data which overflows the 23127 * current viewport. This can be used as an alternative to paging to display 23128 * a lot of data in a small area (although paging and scrolling can both be 23129 * enabled at the same time). This property can be any CSS unit, or a number 23130 * (in which case it will be treated as a pixel measurement). 23131 * @type string 23132 * @default <i>blank string - i.e. disabled</i> 23133 * 23134 * @dtopt Features 23135 * @name DataTable.defaults.scrollY 23136 * 23137 * @example 23138 * $(document).ready( function() { 23139 * $('#example').dataTable( { 23140 * "scrollY": "200px", 23141 * "paginate": false 23142 * } ); 23143 * } ); 23144 */ 23145 "sScrollY": "", 23146 23147 23148 /** 23149 * __Deprecated__ The functionality provided by this parameter has now been 23150 * superseded by that provided through `ajax`, which should be used instead. 23151 * 23152 * Set the HTTP method that is used to make the Ajax call for server-side 23153 * processing or Ajax sourced data. 23154 * @type string 23155 * @default GET 23156 * 23157 * @dtopt Options 23158 * @dtopt Server-side 23159 * @name DataTable.defaults.serverMethod 23160 * 23161 * @deprecated 1.10. Please use `ajax` for this functionality now. 23162 */ 23163 "sServerMethod": "GET", 23164 23165 23166 /** 23167 * DataTables makes use of renderers when displaying HTML elements for 23168 * a table. These renderers can be added or modified by plug-ins to 23169 * generate suitable mark-up for a site. For example the Bootstrap 23170 * integration plug-in for DataTables uses a paging button renderer to 23171 * display pagination buttons in the mark-up required by Bootstrap. 23172 * 23173 * For further information about the renderers available see 23174 * DataTable.ext.renderer 23175 * @type string|object 23176 * @default null 23177 * 23178 * @name DataTable.defaults.renderer 23179 * 23180 */ 23181 "renderer": null, 23182 23183 23184 /** 23185 * Set the data property name that DataTables should use to get a row's id 23186 * to set as the `id` property in the node. 23187 * @type string 23188 * @default DT_RowId 23189 * 23190 * @name DataTable.defaults.rowId 23191 */ 23192 "rowId": "DT_RowId" 23193 }; 23194 23195 _fnHungarianMap( DataTable.defaults ); 23196 23197 23198 23199 /* 23200 * Developer note - See note in model.defaults.js about the use of Hungarian 23201 * notation and camel case. 23202 */ 23203 23204 /** 23205 * Column options that can be given to DataTables at initialisation time. 23206 * @namespace 23207 */ 23208 DataTable.defaults.column = { 23209 /** 23210 * Define which column(s) an order will occur on for this column. This 23211 * allows a column's ordering to take multiple columns into account when 23212 * doing a sort or use the data from a different column. For example first 23213 * name / last name columns make sense to do a multi-column sort over the 23214 * two columns. 23215 * @type array|int 23216 * @default null <i>Takes the value of the column index automatically</i> 23217 * 23218 * @name DataTable.defaults.column.orderData 23219 * @dtopt Columns 23220 * 23221 * @example 23222 * // Using `columnDefs` 23223 * $(document).ready( function() { 23224 * $('#example').dataTable( { 23225 * "columnDefs": [ 23226 * { "orderData": [ 0, 1 ], "targets": [ 0 ] }, 23227 * { "orderData": [ 1, 0 ], "targets": [ 1 ] }, 23228 * { "orderData": 2, "targets": [ 2 ] } 23229 * ] 23230 * } ); 23231 * } ); 23232 * 23233 * @example 23234 * // Using `columns` 23235 * $(document).ready( function() { 23236 * $('#example').dataTable( { 23237 * "columns": [ 23238 * { "orderData": [ 0, 1 ] }, 23239 * { "orderData": [ 1, 0 ] }, 23240 * { "orderData": 2 }, 23241 * null, 23242 * null 23243 * ] 23244 * } ); 23245 * } ); 23246 */ 23247 "aDataSort": null, 23248 "iDataSort": -1, 23249 23250 23251 /** 23252 * You can control the default ordering direction, and even alter the 23253 * behaviour of the sort handler (i.e. only allow ascending ordering etc) 23254 * using this parameter. 23255 * @type array 23256 * @default [ 'asc', 'desc' ] 23257 * 23258 * @name DataTable.defaults.column.orderSequence 23259 * @dtopt Columns 23260 * 23261 * @example 23262 * // Using `columnDefs` 23263 * $(document).ready( function() { 23264 * $('#example').dataTable( { 23265 * "columnDefs": [ 23266 * { "orderSequence": [ "asc" ], "targets": [ 1 ] }, 23267 * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] }, 23268 * { "orderSequence": [ "desc" ], "targets": [ 3 ] } 23269 * ] 23270 * } ); 23271 * } ); 23272 * 23273 * @example 23274 * // Using `columns` 23275 * $(document).ready( function() { 23276 * $('#example').dataTable( { 23277 * "columns": [ 23278 * null, 23279 * { "orderSequence": [ "asc" ] }, 23280 * { "orderSequence": [ "desc", "asc", "asc" ] }, 23281 * { "orderSequence": [ "desc" ] }, 23282 * null 23283 * ] 23284 * } ); 23285 * } ); 23286 */ 23287 "asSorting": [ 'asc', 'desc' ], 23288 23289 23290 /** 23291 * Enable or disable filtering on the data in this column. 23292 * @type boolean 23293 * @default true 23294 * 23295 * @name DataTable.defaults.column.searchable 23296 * @dtopt Columns 23297 * 23298 * @example 23299 * // Using `columnDefs` 23300 * $(document).ready( function() { 23301 * $('#example').dataTable( { 23302 * "columnDefs": [ 23303 * { "searchable": false, "targets": [ 0 ] } 23304 * ] } ); 23305 * } ); 23306 * 23307 * @example 23308 * // Using `columns` 23309 * $(document).ready( function() { 23310 * $('#example').dataTable( { 23311 * "columns": [ 23312 * { "searchable": false }, 23313 * null, 23314 * null, 23315 * null, 23316 * null 23317 * ] } ); 23318 * } ); 23319 */ 23320 "bSearchable": true, 23321 23322 23323 /** 23324 * Enable or disable ordering on this column. 23325 * @type boolean 23326 * @default true 23327 * 23328 * @name DataTable.defaults.column.orderable 23329 * @dtopt Columns 23330 * 23331 * @example 23332 * // Using `columnDefs` 23333 * $(document).ready( function() { 23334 * $('#example').dataTable( { 23335 * "columnDefs": [ 23336 * { "orderable": false, "targets": [ 0 ] } 23337 * ] } ); 23338 * } ); 23339 * 23340 * @example 23341 * // Using `columns` 23342 * $(document).ready( function() { 23343 * $('#example').dataTable( { 23344 * "columns": [ 23345 * { "orderable": false }, 23346 * null, 23347 * null, 23348 * null, 23349 * null 23350 * ] } ); 23351 * } ); 23352 */ 23353 "bSortable": true, 23354 23355 23356 /** 23357 * Enable or disable the display of this column. 23358 * @type boolean 23359 * @default true 23360 * 23361 * @name DataTable.defaults.column.visible 23362 * @dtopt Columns 23363 * 23364 * @example 23365 * // Using `columnDefs` 23366 * $(document).ready( function() { 23367 * $('#example').dataTable( { 23368 * "columnDefs": [ 23369 * { "visible": false, "targets": [ 0 ] } 23370 * ] } ); 23371 * } ); 23372 * 23373 * @example 23374 * // Using `columns` 23375 * $(document).ready( function() { 23376 * $('#example').dataTable( { 23377 * "columns": [ 23378 * { "visible": false }, 23379 * null, 23380 * null, 23381 * null, 23382 * null 23383 * ] } ); 23384 * } ); 23385 */ 23386 "bVisible": true, 23387 23388 23389 /** 23390 * Developer definable function that is called whenever a cell is created (Ajax source, 23391 * etc) or processed for input (DOM source). This can be used as a compliment to mRender 23392 * allowing you to modify the DOM element (add background colour for example) when the 23393 * element is available. 23394 * @type function 23395 * @param {element} td The TD node that has been created 23396 * @param {*} cellData The Data for the cell 23397 * @param {array|object} rowData The data for the whole row 23398 * @param {int} row The row index for the aoData data store 23399 * @param {int} col The column index for aoColumns 23400 * 23401 * @name DataTable.defaults.column.createdCell 23402 * @dtopt Columns 23403 * 23404 * @example 23405 * $(document).ready( function() { 23406 * $('#example').dataTable( { 23407 * "columnDefs": [ { 23408 * "targets": [3], 23409 * "createdCell": function (td, cellData, rowData, row, col) { 23410 * if ( cellData == "1.7" ) { 23411 * $(td).css('color', 'blue') 23412 * } 23413 * } 23414 * } ] 23415 * }); 23416 * } ); 23417 */ 23418 "fnCreatedCell": null, 23419 23420 23421 /** 23422 * This parameter has been replaced by `data` in DataTables to ensure naming 23423 * consistency. `dataProp` can still be used, as there is backwards 23424 * compatibility in DataTables for this option, but it is strongly 23425 * recommended that you use `data` in preference to `dataProp`. 23426 * @name DataTable.defaults.column.dataProp 23427 */ 23428 23429 23430 /** 23431 * This property can be used to read data from any data source property, 23432 * including deeply nested objects / properties. `data` can be given in a 23433 * number of different ways which effect its behaviour: 23434 * 23435 * * `integer` - treated as an array index for the data source. This is the 23436 * default that DataTables uses (incrementally increased for each column). 23437 * * `string` - read an object property from the data source. There are 23438 * three 'special' options that can be used in the string to alter how 23439 * DataTables reads the data from the source object: 23440 * * `.` - Dotted Javascript notation. Just as you use a `.` in 23441 * Javascript to read from nested objects, so to can the options 23442 * specified in `data`. For example: `browser.version` or 23443 * `browser.name`. If your object parameter name contains a period, use 23444 * `\\` to escape it - i.e. `first\\.name`. 23445 * * `[]` - Array notation. DataTables can automatically combine data 23446 * from and array source, joining the data with the characters provided 23447 * between the two brackets. For example: `name[, ]` would provide a 23448 * comma-space separated list from the source array. If no characters 23449 * are provided between the brackets, the original array source is 23450 * returned. 23451 * * `()` - Function notation. Adding `()` to the end of a parameter will 23452 * execute a function of the name given. For example: `browser()` for a 23453 * simple function on the data source, `browser.version()` for a 23454 * function in a nested property or even `browser().version` to get an 23455 * object property if the function called returns an object. Note that 23456 * function notation is recommended for use in `render` rather than 23457 * `data` as it is much simpler to use as a renderer. 23458 * * `null` - use the original data source for the row rather than plucking 23459 * data directly from it. This action has effects on two other 23460 * initialisation options: 23461 * * `defaultContent` - When null is given as the `data` option and 23462 * `defaultContent` is specified for the column, the value defined by 23463 * `defaultContent` will be used for the cell. 23464 * * `render` - When null is used for the `data` option and the `render` 23465 * option is specified for the column, the whole data source for the 23466 * row is used for the renderer. 23467 * * `function` - the function given will be executed whenever DataTables 23468 * needs to set or get the data for a cell in the column. The function 23469 * takes three parameters: 23470 * * Parameters: 23471 * * `{array|object}` The data source for the row 23472 * * `{string}` The type call data requested - this will be 'set' when 23473 * setting data or 'filter', 'display', 'type', 'sort' or undefined 23474 * when gathering data. Note that when `undefined` is given for the 23475 * type DataTables expects to get the raw data for the object back< 23476 * * `{*}` Data to set when the second parameter is 'set'. 23477 * * Return: 23478 * * The return value from the function is not required when 'set' is 23479 * the type of call, but otherwise the return is what will be used 23480 * for the data requested. 23481 * 23482 * Note that `data` is a getter and setter option. If you just require 23483 * formatting of data for output, you will likely want to use `render` which 23484 * is simply a getter and thus simpler to use. 23485 * 23486 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The 23487 * name change reflects the flexibility of this property and is consistent 23488 * with the naming of mRender. If 'mDataProp' is given, then it will still 23489 * be used by DataTables, as it automatically maps the old name to the new 23490 * if required. 23491 * 23492 * @type string|int|function|null 23493 * @default null <i>Use automatically calculated column index</i> 23494 * 23495 * @name DataTable.defaults.column.data 23496 * @dtopt Columns 23497 * 23498 * @example 23499 * // Read table data from objects 23500 * // JSON structure for each row: 23501 * // { 23502 * // "engine": {value}, 23503 * // "browser": {value}, 23504 * // "platform": {value}, 23505 * // "version": {value}, 23506 * // "grade": {value} 23507 * // } 23508 * $(document).ready( function() { 23509 * $('#example').dataTable( { 23510 * "ajaxSource": "sources/objects.txt", 23511 * "columns": [ 23512 * { "data": "engine" }, 23513 * { "data": "browser" }, 23514 * { "data": "platform" }, 23515 * { "data": "version" }, 23516 * { "data": "grade" } 23517 * ] 23518 * } ); 23519 * } ); 23520 * 23521 * @example 23522 * // Read information from deeply nested objects 23523 * // JSON structure for each row: 23524 * // { 23525 * // "engine": {value}, 23526 * // "browser": {value}, 23527 * // "platform": { 23528 * // "inner": {value} 23529 * // }, 23530 * // "details": [ 23531 * // {value}, {value} 23532 * // ] 23533 * // } 23534 * $(document).ready( function() { 23535 * $('#example').dataTable( { 23536 * "ajaxSource": "sources/deep.txt", 23537 * "columns": [ 23538 * { "data": "engine" }, 23539 * { "data": "browser" }, 23540 * { "data": "platform.inner" }, 23541 * { "data": "details.0" }, 23542 * { "data": "details.1" } 23543 * ] 23544 * } ); 23545 * } ); 23546 * 23547 * @example 23548 * // Using `data` as a function to provide different information for 23549 * // sorting, filtering and display. In this case, currency (price) 23550 * $(document).ready( function() { 23551 * $('#example').dataTable( { 23552 * "columnDefs": [ { 23553 * "targets": [ 0 ], 23554 * "data": function ( source, type, val ) { 23555 * if (type === 'set') { 23556 * source.price = val; 23557 * // Store the computed display and filter values for efficiency 23558 * source.price_display = val=="" ? "" : "$"+numberFormat(val); 23559 * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val; 23560 * return; 23561 * } 23562 * else if (type === 'display') { 23563 * return source.price_display; 23564 * } 23565 * else if (type === 'filter') { 23566 * return source.price_filter; 23567 * } 23568 * // 'sort', 'type' and undefined all just use the integer 23569 * return source.price; 23570 * } 23571 * } ] 23572 * } ); 23573 * } ); 23574 * 23575 * @example 23576 * // Using default content 23577 * $(document).ready( function() { 23578 * $('#example').dataTable( { 23579 * "columnDefs": [ { 23580 * "targets": [ 0 ], 23581 * "data": null, 23582 * "defaultContent": "Click to edit" 23583 * } ] 23584 * } ); 23585 * } ); 23586 * 23587 * @example 23588 * // Using array notation - outputting a list from an array 23589 * $(document).ready( function() { 23590 * $('#example').dataTable( { 23591 * "columnDefs": [ { 23592 * "targets": [ 0 ], 23593 * "data": "name[, ]" 23594 * } ] 23595 * } ); 23596 * } ); 23597 * 23598 */ 23599 "mData": null, 23600 23601 23602 /** 23603 * This property is the rendering partner to `data` and it is suggested that 23604 * when you want to manipulate data for display (including filtering, 23605 * sorting etc) without altering the underlying data for the table, use this 23606 * property. `render` can be considered to be the the read only companion to 23607 * `data` which is read / write (then as such more complex). Like `data` 23608 * this option can be given in a number of different ways to effect its 23609 * behaviour: 23610 * 23611 * * `integer` - treated as an array index for the data source. This is the 23612 * default that DataTables uses (incrementally increased for each column). 23613 * * `string` - read an object property from the data source. There are 23614 * three 'special' options that can be used in the string to alter how 23615 * DataTables reads the data from the source object: 23616 * * `.` - Dotted Javascript notation. Just as you use a `.` in 23617 * Javascript to read from nested objects, so to can the options 23618 * specified in `data`. For example: `browser.version` or 23619 * `browser.name`. If your object parameter name contains a period, use 23620 * `\\` to escape it - i.e. `first\\.name`. 23621 * * `[]` - Array notation. DataTables can automatically combine data 23622 * from and array source, joining the data with the characters provided 23623 * between the two brackets. For example: `name[, ]` would provide a 23624 * comma-space separated list from the source array. If no characters 23625 * are provided between the brackets, the original array source is 23626 * returned. 23627 * * `()` - Function notation. Adding `()` to the end of a parameter will 23628 * execute a function of the name given. For example: `browser()` for a 23629 * simple function on the data source, `browser.version()` for a 23630 * function in a nested property or even `browser().version` to get an 23631 * object property if the function called returns an object. 23632 * * `object` - use different data for the different data types requested by 23633 * DataTables ('filter', 'display', 'type' or 'sort'). The property names 23634 * of the object is the data type the property refers to and the value can 23635 * defined using an integer, string or function using the same rules as 23636 * `render` normally does. Note that an `_` option _must_ be specified. 23637 * This is the default value to use if you haven't specified a value for 23638 * the data type requested by DataTables. 23639 * * `function` - the function given will be executed whenever DataTables 23640 * needs to set or get the data for a cell in the column. The function 23641 * takes three parameters: 23642 * * Parameters: 23643 * * {array|object} The data source for the row (based on `data`) 23644 * * {string} The type call data requested - this will be 'filter', 23645 * 'display', 'type' or 'sort'. 23646 * * {array|object} The full data source for the row (not based on 23647 * `data`) 23648 * * Return: 23649 * * The return value from the function is what will be used for the 23650 * data requested. 23651 * 23652 * @type string|int|function|object|null 23653 * @default null Use the data source value. 23654 * 23655 * @name DataTable.defaults.column.render 23656 * @dtopt Columns 23657 * 23658 * @example 23659 * // Create a comma separated list from an array of objects 23660 * $(document).ready( function() { 23661 * $('#example').dataTable( { 23662 * "ajaxSource": "sources/deep.txt", 23663 * "columns": [ 23664 * { "data": "engine" }, 23665 * { "data": "browser" }, 23666 * { 23667 * "data": "platform", 23668 * "render": "[, ].name" 23669 * } 23670 * ] 23671 * } ); 23672 * } ); 23673 * 23674 * @example 23675 * // Execute a function to obtain data 23676 * $(document).ready( function() { 23677 * $('#example').dataTable( { 23678 * "columnDefs": [ { 23679 * "targets": [ 0 ], 23680 * "data": null, // Use the full data source object for the renderer's source 23681 * "render": "browserName()" 23682 * } ] 23683 * } ); 23684 * } ); 23685 * 23686 * @example 23687 * // As an object, extracting different data for the different types 23688 * // This would be used with a data source such as: 23689 * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" } 23690 * // Here the `phone` integer is used for sorting and type detection, while `phone_filter` 23691 * // (which has both forms) is used for filtering for if a user inputs either format, while 23692 * // the formatted phone number is the one that is shown in the table. 23693 * $(document).ready( function() { 23694 * $('#example').dataTable( { 23695 * "columnDefs": [ { 23696 * "targets": [ 0 ], 23697 * "data": null, // Use the full data source object for the renderer's source 23698 * "render": { 23699 * "_": "phone", 23700 * "filter": "phone_filter", 23701 * "display": "phone_display" 23702 * } 23703 * } ] 23704 * } ); 23705 * } ); 23706 * 23707 * @example 23708 * // Use as a function to create a link from the data source 23709 * $(document).ready( function() { 23710 * $('#example').dataTable( { 23711 * "columnDefs": [ { 23712 * "targets": [ 0 ], 23713 * "data": "download_link", 23714 * "render": function ( data, type, full ) { 23715 * return '<a href="'+data+'">Download</a>'; 23716 * } 23717 * } ] 23718 * } ); 23719 * } ); 23720 */ 23721 "mRender": null, 23722 23723 23724 /** 23725 * Change the cell type created for the column - either TD cells or TH cells. This 23726 * can be useful as TH cells have semantic meaning in the table body, allowing them 23727 * to act as a header for a row (you may wish to add scope='row' to the TH elements). 23728 * @type string 23729 * @default td 23730 * 23731 * @name DataTable.defaults.column.cellType 23732 * @dtopt Columns 23733 * 23734 * @example 23735 * // Make the first column use TH cells 23736 * $(document).ready( function() { 23737 * $('#example').dataTable( { 23738 * "columnDefs": [ { 23739 * "targets": [ 0 ], 23740 * "cellType": "th" 23741 * } ] 23742 * } ); 23743 * } ); 23744 */ 23745 "sCellType": "td", 23746 23747 23748 /** 23749 * Class to give to each cell in this column. 23750 * @type string 23751 * @default <i>Empty string</i> 23752 * 23753 * @name DataTable.defaults.column.class 23754 * @dtopt Columns 23755 * 23756 * @example 23757 * // Using `columnDefs` 23758 * $(document).ready( function() { 23759 * $('#example').dataTable( { 23760 * "columnDefs": [ 23761 * { "class": "my_class", "targets": [ 0 ] } 23762 * ] 23763 * } ); 23764 * } ); 23765 * 23766 * @example 23767 * // Using `columns` 23768 * $(document).ready( function() { 23769 * $('#example').dataTable( { 23770 * "columns": [ 23771 * { "class": "my_class" }, 23772 * null, 23773 * null, 23774 * null, 23775 * null 23776 * ] 23777 * } ); 23778 * } ); 23779 */ 23780 "sClass": "", 23781 23782 /** 23783 * When DataTables calculates the column widths to assign to each column, 23784 * it finds the longest string in each column and then constructs a 23785 * temporary table and reads the widths from that. The problem with this 23786 * is that "mmm" is much wider then "iiii", but the latter is a longer 23787 * string - thus the calculation can go wrong (doing it properly and putting 23788 * it into an DOM object and measuring that is horribly(!) slow). Thus as 23789 * a "work around" we provide this option. It will append its value to the 23790 * text that is found to be the longest string for the column - i.e. padding. 23791 * Generally you shouldn't need this! 23792 * @type string 23793 * @default <i>Empty string<i> 23794 * 23795 * @name DataTable.defaults.column.contentPadding 23796 * @dtopt Columns 23797 * 23798 * @example 23799 * // Using `columns` 23800 * $(document).ready( function() { 23801 * $('#example').dataTable( { 23802 * "columns": [ 23803 * null, 23804 * null, 23805 * null, 23806 * { 23807 * "contentPadding": "mmm" 23808 * } 23809 * ] 23810 * } ); 23811 * } ); 23812 */ 23813 "sContentPadding": "", 23814 23815 23816 /** 23817 * Allows a default value to be given for a column's data, and will be used 23818 * whenever a null data source is encountered (this can be because `data` 23819 * is set to null, or because the data source itself is null). 23820 * @type string 23821 * @default null 23822 * 23823 * @name DataTable.defaults.column.defaultContent 23824 * @dtopt Columns 23825 * 23826 * @example 23827 * // Using `columnDefs` 23828 * $(document).ready( function() { 23829 * $('#example').dataTable( { 23830 * "columnDefs": [ 23831 * { 23832 * "data": null, 23833 * "defaultContent": "Edit", 23834 * "targets": [ -1 ] 23835 * } 23836 * ] 23837 * } ); 23838 * } ); 23839 * 23840 * @example 23841 * // Using `columns` 23842 * $(document).ready( function() { 23843 * $('#example').dataTable( { 23844 * "columns": [ 23845 * null, 23846 * null, 23847 * null, 23848 * { 23849 * "data": null, 23850 * "defaultContent": "Edit" 23851 * } 23852 * ] 23853 * } ); 23854 * } ); 23855 */ 23856 "sDefaultContent": null, 23857 23858 23859 /** 23860 * This parameter is only used in DataTables' server-side processing. It can 23861 * be exceptionally useful to know what columns are being displayed on the 23862 * client side, and to map these to database fields. When defined, the names 23863 * also allow DataTables to reorder information from the server if it comes 23864 * back in an unexpected order (i.e. if you switch your columns around on the 23865 * client-side, your server-side code does not also need updating). 23866 * @type string 23867 * @default <i>Empty string</i> 23868 * 23869 * @name DataTable.defaults.column.name 23870 * @dtopt Columns 23871 * 23872 * @example 23873 * // Using `columnDefs` 23874 * $(document).ready( function() { 23875 * $('#example').dataTable( { 23876 * "columnDefs": [ 23877 * { "name": "engine", "targets": [ 0 ] }, 23878 * { "name": "browser", "targets": [ 1 ] }, 23879 * { "name": "platform", "targets": [ 2 ] }, 23880 * { "name": "version", "targets": [ 3 ] }, 23881 * { "name": "grade", "targets": [ 4 ] } 23882 * ] 23883 * } ); 23884 * } ); 23885 * 23886 * @example 23887 * // Using `columns` 23888 * $(document).ready( function() { 23889 * $('#example').dataTable( { 23890 * "columns": [ 23891 * { "name": "engine" }, 23892 * { "name": "browser" }, 23893 * { "name": "platform" }, 23894 * { "name": "version" }, 23895 * { "name": "grade" } 23896 * ] 23897 * } ); 23898 * } ); 23899 */ 23900 "sName": "", 23901 23902 23903 /** 23904 * Defines a data source type for the ordering which can be used to read 23905 * real-time information from the table (updating the internally cached 23906 * version) prior to ordering. This allows ordering to occur on user 23907 * editable elements such as form inputs. 23908 * @type string 23909 * @default std 23910 * 23911 * @name DataTable.defaults.column.orderDataType 23912 * @dtopt Columns 23913 * 23914 * @example 23915 * // Using `columnDefs` 23916 * $(document).ready( function() { 23917 * $('#example').dataTable( { 23918 * "columnDefs": [ 23919 * { "orderDataType": "dom-text", "targets": [ 2, 3 ] }, 23920 * { "type": "numeric", "targets": [ 3 ] }, 23921 * { "orderDataType": "dom-select", "targets": [ 4 ] }, 23922 * { "orderDataType": "dom-checkbox", "targets": [ 5 ] } 23923 * ] 23924 * } ); 23925 * } ); 23926 * 23927 * @example 23928 * // Using `columns` 23929 * $(document).ready( function() { 23930 * $('#example').dataTable( { 23931 * "columns": [ 23932 * null, 23933 * null, 23934 * { "orderDataType": "dom-text" }, 23935 * { "orderDataType": "dom-text", "type": "numeric" }, 23936 * { "orderDataType": "dom-select" }, 23937 * { "orderDataType": "dom-checkbox" } 23938 * ] 23939 * } ); 23940 * } ); 23941 */ 23942 "sSortDataType": "std", 23943 23944 23945 /** 23946 * The title of this column. 23947 * @type string 23948 * @default null <i>Derived from the 'TH' value for this column in the 23949 * original HTML table.</i> 23950 * 23951 * @name DataTable.defaults.column.title 23952 * @dtopt Columns 23953 * 23954 * @example 23955 * // Using `columnDefs` 23956 * $(document).ready( function() { 23957 * $('#example').dataTable( { 23958 * "columnDefs": [ 23959 * { "title": "My column title", "targets": [ 0 ] } 23960 * ] 23961 * } ); 23962 * } ); 23963 * 23964 * @example 23965 * // Using `columns` 23966 * $(document).ready( function() { 23967 * $('#example').dataTable( { 23968 * "columns": [ 23969 * { "title": "My column title" }, 23970 * null, 23971 * null, 23972 * null, 23973 * null 23974 * ] 23975 * } ); 23976 * } ); 23977 */ 23978 "sTitle": null, 23979 23980 23981 /** 23982 * The type allows you to specify how the data for this column will be 23983 * ordered. Four types (string, numeric, date and html (which will strip 23984 * HTML tags before ordering)) are currently available. Note that only date 23985 * formats understood by Javascript's Date() object will be accepted as type 23986 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 23987 * 'numeric', 'date' or 'html' (by default). Further types can be adding 23988 * through plug-ins. 23989 * @type string 23990 * @default null <i>Auto-detected from raw data</i> 23991 * 23992 * @name DataTable.defaults.column.type 23993 * @dtopt Columns 23994 * 23995 * @example 23996 * // Using `columnDefs` 23997 * $(document).ready( function() { 23998 * $('#example').dataTable( { 23999 * "columnDefs": [ 24000 * { "type": "html", "targets": [ 0 ] } 24001 * ] 24002 * } ); 24003 * } ); 24004 * 24005 * @example 24006 * // Using `columns` 24007 * $(document).ready( function() { 24008 * $('#example').dataTable( { 24009 * "columns": [ 24010 * { "type": "html" }, 24011 * null, 24012 * null, 24013 * null, 24014 * null 24015 * ] 24016 * } ); 24017 * } ); 24018 */ 24019 "sType": null, 24020 24021 24022 /** 24023 * Defining the width of the column, this parameter may take any CSS value 24024 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not 24025 * been given a specific width through this interface ensuring that the table 24026 * remains readable. 24027 * @type string 24028 * @default null <i>Automatic</i> 24029 * 24030 * @name DataTable.defaults.column.width 24031 * @dtopt Columns 24032 * 24033 * @example 24034 * // Using `columnDefs` 24035 * $(document).ready( function() { 24036 * $('#example').dataTable( { 24037 * "columnDefs": [ 24038 * { "width": "20%", "targets": [ 0 ] } 24039 * ] 24040 * } ); 24041 * } ); 24042 * 24043 * @example 24044 * // Using `columns` 24045 * $(document).ready( function() { 24046 * $('#example').dataTable( { 24047 * "columns": [ 24048 * { "width": "20%" }, 24049 * null, 24050 * null, 24051 * null, 24052 * null 24053 * ] 24054 * } ); 24055 * } ); 24056 */ 24057 "sWidth": null 24058 }; 24059 24060 _fnHungarianMap( DataTable.defaults.column ); 24061 24062 24063 24064 /** 24065 * DataTables settings object - this holds all the information needed for a 24066 * given table, including configuration, data and current application of the 24067 * table options. DataTables does not have a single instance for each DataTable 24068 * with the settings attached to that instance, but rather instances of the 24069 * DataTable "class" are created on-the-fly as needed (typically by a 24070 * $().dataTable() call) and the settings object is then applied to that 24071 * instance. 24072 * 24073 * Note that this object is related to {@link DataTable.defaults} but this 24074 * one is the internal data store for DataTables's cache of columns. It should 24075 * NOT be manipulated outside of DataTables. Any configuration should be done 24076 * through the initialisation options. 24077 * @namespace 24078 * @todo Really should attach the settings object to individual instances so we 24079 * don't need to create new instances on each $().dataTable() call (if the 24080 * table already exists). It would also save passing oSettings around and 24081 * into every single function. However, this is a very significant 24082 * architecture change for DataTables and will almost certainly break 24083 * backwards compatibility with older installations. This is something that 24084 * will be done in 2.0. 24085 */ 24086 DataTable.models.oSettings = { 24087 /** 24088 * Primary features of DataTables and their enablement state. 24089 * @namespace 24090 */ 24091 "oFeatures": { 24092 24093 /** 24094 * Flag to say if DataTables should automatically try to calculate the 24095 * optimum table and columns widths (true) or not (false). 24096 * Note that this parameter will be set by the initialisation routine. To 24097 * set a default use {@link DataTable.defaults}. 24098 * @type boolean 24099 */ 24100 "bAutoWidth": null, 24101 24102 /** 24103 * Delay the creation of TR and TD elements until they are actually 24104 * needed by a driven page draw. This can give a significant speed 24105 * increase for Ajax source and Javascript source data, but makes no 24106 * difference at all for DOM and server-side processing tables. 24107 * Note that this parameter will be set by the initialisation routine. To 24108 * set a default use {@link DataTable.defaults}. 24109 * @type boolean 24110 */ 24111 "bDeferRender": null, 24112 24113 /** 24114 * Enable filtering on the table or not. Note that if this is disabled 24115 * then there is no filtering at all on the table, including fnFilter. 24116 * To just remove the filtering input use sDom and remove the 'f' option. 24117 * Note that this parameter will be set by the initialisation routine. To 24118 * set a default use {@link DataTable.defaults}. 24119 * @type boolean 24120 */ 24121 "bFilter": null, 24122 24123 /** 24124 * Table information element (the 'Showing x of y records' div) enable 24125 * flag. 24126 * Note that this parameter will be set by the initialisation routine. To 24127 * set a default use {@link DataTable.defaults}. 24128 * @type boolean 24129 */ 24130 "bInfo": null, 24131 24132 /** 24133 * Present a user control allowing the end user to change the page size 24134 * when pagination is enabled. 24135 * Note that this parameter will be set by the initialisation routine. To 24136 * set a default use {@link DataTable.defaults}. 24137 * @type boolean 24138 */ 24139 "bLengthChange": null, 24140 24141 /** 24142 * Pagination enabled or not. Note that if this is disabled then length 24143 * changing must also be disabled. 24144 * Note that this parameter will be set by the initialisation routine. To 24145 * set a default use {@link DataTable.defaults}. 24146 * @type boolean 24147 */ 24148 "bPaginate": null, 24149 24150 /** 24151 * Processing indicator enable flag whenever DataTables is enacting a 24152 * user request - typically an Ajax request for server-side processing. 24153 * Note that this parameter will be set by the initialisation routine. To 24154 * set a default use {@link DataTable.defaults}. 24155 * @type boolean 24156 */ 24157 "bProcessing": null, 24158 24159 /** 24160 * Server-side processing enabled flag - when enabled DataTables will 24161 * get all data from the server for every draw - there is no filtering, 24162 * sorting or paging done on the client-side. 24163 * Note that this parameter will be set by the initialisation routine. To 24164 * set a default use {@link DataTable.defaults}. 24165 * @type boolean 24166 */ 24167 "bServerSide": null, 24168 24169 /** 24170 * Sorting enablement flag. 24171 * Note that this parameter will be set by the initialisation routine. To 24172 * set a default use {@link DataTable.defaults}. 24173 * @type boolean 24174 */ 24175 "bSort": null, 24176 24177 /** 24178 * Multi-column sorting 24179 * Note that this parameter will be set by the initialisation routine. To 24180 * set a default use {@link DataTable.defaults}. 24181 * @type boolean 24182 */ 24183 "bSortMulti": null, 24184 24185 /** 24186 * Apply a class to the columns which are being sorted to provide a 24187 * visual highlight or not. This can slow things down when enabled since 24188 * there is a lot of DOM interaction. 24189 * Note that this parameter will be set by the initialisation routine. To 24190 * set a default use {@link DataTable.defaults}. 24191 * @type boolean 24192 */ 24193 "bSortClasses": null, 24194 24195 /** 24196 * State saving enablement flag. 24197 * Note that this parameter will be set by the initialisation routine. To 24198 * set a default use {@link DataTable.defaults}. 24199 * @type boolean 24200 */ 24201 "bStateSave": null 24202 }, 24203 24204 24205 /** 24206 * Scrolling settings for a table. 24207 * @namespace 24208 */ 24209 "oScroll": { 24210 /** 24211 * When the table is shorter in height than sScrollY, collapse the 24212 * table container down to the height of the table (when true). 24213 * Note that this parameter will be set by the initialisation routine. To 24214 * set a default use {@link DataTable.defaults}. 24215 * @type boolean 24216 */ 24217 "bCollapse": null, 24218 24219 /** 24220 * Width of the scrollbar for the web-browser's platform. Calculated 24221 * during table initialisation. 24222 * @type int 24223 * @default 0 24224 */ 24225 "iBarWidth": 0, 24226 24227 /** 24228 * Viewport width for horizontal scrolling. Horizontal scrolling is 24229 * disabled if an empty string. 24230 * Note that this parameter will be set by the initialisation routine. To 24231 * set a default use {@link DataTable.defaults}. 24232 * @type string 24233 */ 24234 "sX": null, 24235 24236 /** 24237 * Width to expand the table to when using x-scrolling. Typically you 24238 * should not need to use this. 24239 * Note that this parameter will be set by the initialisation routine. To 24240 * set a default use {@link DataTable.defaults}. 24241 * @type string 24242 * @deprecated 24243 */ 24244 "sXInner": null, 24245 24246 /** 24247 * Viewport height for vertical scrolling. Vertical scrolling is disabled 24248 * if an empty string. 24249 * Note that this parameter will be set by the initialisation routine. To 24250 * set a default use {@link DataTable.defaults}. 24251 * @type string 24252 */ 24253 "sY": null 24254 }, 24255 24256 /** 24257 * Language information for the table. 24258 * @namespace 24259 * @extends DataTable.defaults.oLanguage 24260 */ 24261 "oLanguage": { 24262 /** 24263 * Information callback function. See 24264 * {@link DataTable.defaults.fnInfoCallback} 24265 * @type function 24266 * @default null 24267 */ 24268 "fnInfoCallback": null 24269 }, 24270 24271 /** 24272 * Browser support parameters 24273 * @namespace 24274 */ 24275 "oBrowser": { 24276 /** 24277 * Indicate if the browser incorrectly calculates width:100% inside a 24278 * scrolling element (IE6/7) 24279 * @type boolean 24280 * @default false 24281 */ 24282 "bScrollOversize": false, 24283 24284 /** 24285 * Determine if the vertical scrollbar is on the right or left of the 24286 * scrolling container - needed for rtl language layout, although not 24287 * all browsers move the scrollbar (Safari). 24288 * @type boolean 24289 * @default false 24290 */ 24291 "bScrollbarLeft": false, 24292 24293 /** 24294 * Flag for if `getBoundingClientRect` is fully supported or not 24295 * @type boolean 24296 * @default false 24297 */ 24298 "bBounding": false, 24299 24300 /** 24301 * Browser scrollbar width 24302 * @type integer 24303 * @default 0 24304 */ 24305 "barWidth": 0 24306 }, 24307 24308 24309 "ajax": null, 24310 24311 24312 /** 24313 * Array referencing the nodes which are used for the features. The 24314 * parameters of this object match what is allowed by sDom - i.e. 24315 * <ul> 24316 * <li>'l' - Length changing</li> 24317 * <li>'f' - Filtering input</li> 24318 * <li>'t' - The table!</li> 24319 * <li>'i' - Information</li> 24320 * <li>'p' - Pagination</li> 24321 * <li>'r' - pRocessing</li> 24322 * </ul> 24323 * @type array 24324 * @default [] 24325 */ 24326 "aanFeatures": [], 24327 24328 /** 24329 * Store data information - see {@link DataTable.models.oRow} for detailed 24330 * information. 24331 * @type array 24332 * @default [] 24333 */ 24334 "aoData": [], 24335 24336 /** 24337 * Array of indexes which are in the current display (after filtering etc) 24338 * @type array 24339 * @default [] 24340 */ 24341 "aiDisplay": [], 24342 24343 /** 24344 * Array of indexes for display - no filtering 24345 * @type array 24346 * @default [] 24347 */ 24348 "aiDisplayMaster": [], 24349 24350 /** 24351 * Map of row ids to data indexes 24352 * @type object 24353 * @default {} 24354 */ 24355 "aIds": {}, 24356 24357 /** 24358 * Store information about each column that is in use 24359 * @type array 24360 * @default [] 24361 */ 24362 "aoColumns": [], 24363 24364 /** 24365 * Store information about the table's header 24366 * @type array 24367 * @default [] 24368 */ 24369 "aoHeader": [], 24370 24371 /** 24372 * Store information about the table's footer 24373 * @type array 24374 * @default [] 24375 */ 24376 "aoFooter": [], 24377 24378 /** 24379 * Store the applied global search information in case we want to force a 24380 * research or compare the old search to a new one. 24381 * Note that this parameter will be set by the initialisation routine. To 24382 * set a default use {@link DataTable.defaults}. 24383 * @namespace 24384 * @extends DataTable.models.oSearch 24385 */ 24386 "oPreviousSearch": {}, 24387 24388 /** 24389 * Store the applied search for each column - see 24390 * {@link DataTable.models.oSearch} for the format that is used for the 24391 * filtering information for each column. 24392 * @type array 24393 * @default [] 24394 */ 24395 "aoPreSearchCols": [], 24396 24397 /** 24398 * Sorting that is applied to the table. Note that the inner arrays are 24399 * used in the following manner: 24400 * <ul> 24401 * <li>Index 0 - column number</li> 24402 * <li>Index 1 - current sorting direction</li> 24403 * </ul> 24404 * Note that this parameter will be set by the initialisation routine. To 24405 * set a default use {@link DataTable.defaults}. 24406 * @type array 24407 * @todo These inner arrays should really be objects 24408 */ 24409 "aaSorting": null, 24410 24411 /** 24412 * Sorting that is always applied to the table (i.e. prefixed in front of 24413 * aaSorting). 24414 * Note that this parameter will be set by the initialisation routine. To 24415 * set a default use {@link DataTable.defaults}. 24416 * @type array 24417 * @default [] 24418 */ 24419 "aaSortingFixed": [], 24420 24421 /** 24422 * Classes to use for the striping of a table. 24423 * Note that this parameter will be set by the initialisation routine. To 24424 * set a default use {@link DataTable.defaults}. 24425 * @type array 24426 * @default [] 24427 */ 24428 "asStripeClasses": null, 24429 24430 /** 24431 * If restoring a table - we should restore its striping classes as well 24432 * @type array 24433 * @default [] 24434 */ 24435 "asDestroyStripes": [], 24436 24437 /** 24438 * If restoring a table - we should restore its width 24439 * @type int 24440 * @default 0 24441 */ 24442 "sDestroyWidth": 0, 24443 24444 /** 24445 * Callback functions array for every time a row is inserted (i.e. on a draw). 24446 * @type array 24447 * @default [] 24448 */ 24449 "aoRowCallback": [], 24450 24451 /** 24452 * Callback functions for the header on each draw. 24453 * @type array 24454 * @default [] 24455 */ 24456 "aoHeaderCallback": [], 24457 24458 /** 24459 * Callback function for the footer on each draw. 24460 * @type array 24461 * @default [] 24462 */ 24463 "aoFooterCallback": [], 24464 24465 /** 24466 * Array of callback functions for draw callback functions 24467 * @type array 24468 * @default [] 24469 */ 24470 "aoDrawCallback": [], 24471 24472 /** 24473 * Array of callback functions for row created function 24474 * @type array 24475 * @default [] 24476 */ 24477 "aoRowCreatedCallback": [], 24478 24479 /** 24480 * Callback functions for just before the table is redrawn. A return of 24481 * false will be used to cancel the draw. 24482 * @type array 24483 * @default [] 24484 */ 24485 "aoPreDrawCallback": [], 24486 24487 /** 24488 * Callback functions for when the table has been initialised. 24489 * @type array 24490 * @default [] 24491 */ 24492 "aoInitComplete": [], 24493 24494 24495 /** 24496 * Callbacks for modifying the settings to be stored for state saving, prior to 24497 * saving state. 24498 * @type array 24499 * @default [] 24500 */ 24501 "aoStateSaveParams": [], 24502 24503 /** 24504 * Callbacks for modifying the settings that have been stored for state saving 24505 * prior to using the stored values to restore the state. 24506 * @type array 24507 * @default [] 24508 */ 24509 "aoStateLoadParams": [], 24510 24511 /** 24512 * Callbacks for operating on the settings object once the saved state has been 24513 * loaded 24514 * @type array 24515 * @default [] 24516 */ 24517 "aoStateLoaded": [], 24518 24519 /** 24520 * Cache the table ID for quick access 24521 * @type string 24522 * @default <i>Empty string</i> 24523 */ 24524 "sTableId": "", 24525 24526 /** 24527 * The TABLE node for the main table 24528 * @type node 24529 * @default null 24530 */ 24531 "nTable": null, 24532 24533 /** 24534 * Permanent ref to the thead element 24535 * @type node 24536 * @default null 24537 */ 24538 "nTHead": null, 24539 24540 /** 24541 * Permanent ref to the tfoot element - if it exists 24542 * @type node 24543 * @default null 24544 */ 24545 "nTFoot": null, 24546 24547 /** 24548 * Permanent ref to the tbody element 24549 * @type node 24550 * @default null 24551 */ 24552 "nTBody": null, 24553 24554 /** 24555 * Cache the wrapper node (contains all DataTables controlled elements) 24556 * @type node 24557 * @default null 24558 */ 24559 "nTableWrapper": null, 24560 24561 /** 24562 * Indicate if when using server-side processing the loading of data 24563 * should be deferred until the second draw. 24564 * Note that this parameter will be set by the initialisation routine. To 24565 * set a default use {@link DataTable.defaults}. 24566 * @type boolean 24567 * @default false 24568 */ 24569 "bDeferLoading": false, 24570 24571 /** 24572 * Indicate if all required information has been read in 24573 * @type boolean 24574 * @default false 24575 */ 24576 "bInitialised": false, 24577 24578 /** 24579 * Information about open rows. Each object in the array has the parameters 24580 * 'nTr' and 'nParent' 24581 * @type array 24582 * @default [] 24583 */ 24584 "aoOpenRows": [], 24585 24586 /** 24587 * Dictate the positioning of DataTables' control elements - see 24588 * {@link DataTable.model.oInit.sDom}. 24589 * Note that this parameter will be set by the initialisation routine. To 24590 * set a default use {@link DataTable.defaults}. 24591 * @type string 24592 * @default null 24593 */ 24594 "sDom": null, 24595 24596 /** 24597 * Search delay (in mS) 24598 * @type integer 24599 * @default null 24600 */ 24601 "searchDelay": null, 24602 24603 /** 24604 * Which type of pagination should be used. 24605 * Note that this parameter will be set by the initialisation routine. To 24606 * set a default use {@link DataTable.defaults}. 24607 * @type string 24608 * @default two_button 24609 */ 24610 "sPaginationType": "two_button", 24611 24612 /** 24613 * The state duration (for `stateSave`) in seconds. 24614 * Note that this parameter will be set by the initialisation routine. To 24615 * set a default use {@link DataTable.defaults}. 24616 * @type int 24617 * @default 0 24618 */ 24619 "iStateDuration": 0, 24620 24621 /** 24622 * Array of callback functions for state saving. Each array element is an 24623 * object with the following parameters: 24624 * <ul> 24625 * <li>function:fn - function to call. Takes two parameters, oSettings 24626 * and the JSON string to save that has been thus far created. Returns 24627 * a JSON string to be inserted into a json object 24628 * (i.e. '"param": [ 0, 1, 2]')</li> 24629 * <li>string:sName - name of callback</li> 24630 * </ul> 24631 * @type array 24632 * @default [] 24633 */ 24634 "aoStateSave": [], 24635 24636 /** 24637 * Array of callback functions for state loading. Each array element is an 24638 * object with the following parameters: 24639 * <ul> 24640 * <li>function:fn - function to call. Takes two parameters, oSettings 24641 * and the object stored. May return false to cancel state loading</li> 24642 * <li>string:sName - name of callback</li> 24643 * </ul> 24644 * @type array 24645 * @default [] 24646 */ 24647 "aoStateLoad": [], 24648 24649 /** 24650 * State that was saved. Useful for back reference 24651 * @type object 24652 * @default null 24653 */ 24654 "oSavedState": null, 24655 24656 /** 24657 * State that was loaded. Useful for back reference 24658 * @type object 24659 * @default null 24660 */ 24661 "oLoadedState": null, 24662 24663 /** 24664 * Source url for AJAX data for the table. 24665 * Note that this parameter will be set by the initialisation routine. To 24666 * set a default use {@link DataTable.defaults}. 24667 * @type string 24668 * @default null 24669 */ 24670 "sAjaxSource": null, 24671 24672 /** 24673 * Property from a given object from which to read the table data from. This 24674 * can be an empty string (when not server-side processing), in which case 24675 * it is assumed an an array is given directly. 24676 * Note that this parameter will be set by the initialisation routine. To 24677 * set a default use {@link DataTable.defaults}. 24678 * @type string 24679 */ 24680 "sAjaxDataProp": null, 24681 24682 /** 24683 * The last jQuery XHR object that was used for server-side data gathering. 24684 * This can be used for working with the XHR information in one of the 24685 * callbacks 24686 * @type object 24687 * @default null 24688 */ 24689 "jqXHR": null, 24690 24691 /** 24692 * JSON returned from the server in the last Ajax request 24693 * @type object 24694 * @default undefined 24695 */ 24696 "json": undefined, 24697 24698 /** 24699 * Data submitted as part of the last Ajax request 24700 * @type object 24701 * @default undefined 24702 */ 24703 "oAjaxData": undefined, 24704 24705 /** 24706 * Function to get the server-side data. 24707 * Note that this parameter will be set by the initialisation routine. To 24708 * set a default use {@link DataTable.defaults}. 24709 * @type function 24710 */ 24711 "fnServerData": null, 24712 24713 /** 24714 * Functions which are called prior to sending an Ajax request so extra 24715 * parameters can easily be sent to the server 24716 * @type array 24717 * @default [] 24718 */ 24719 "aoServerParams": [], 24720 24721 /** 24722 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if 24723 * required). 24724 * Note that this parameter will be set by the initialisation routine. To 24725 * set a default use {@link DataTable.defaults}. 24726 * @type string 24727 */ 24728 "sServerMethod": null, 24729 24730 /** 24731 * Format numbers for display. 24732 * Note that this parameter will be set by the initialisation routine. To 24733 * set a default use {@link DataTable.defaults}. 24734 * @type function 24735 */ 24736 "fnFormatNumber": null, 24737 24738 /** 24739 * List of options that can be used for the user selectable length menu. 24740 * Note that this parameter will be set by the initialisation routine. To 24741 * set a default use {@link DataTable.defaults}. 24742 * @type array 24743 * @default [] 24744 */ 24745 "aLengthMenu": null, 24746 24747 /** 24748 * Counter for the draws that the table does. Also used as a tracker for 24749 * server-side processing 24750 * @type int 24751 * @default 0 24752 */ 24753 "iDraw": 0, 24754 24755 /** 24756 * Indicate if a redraw is being done - useful for Ajax 24757 * @type boolean 24758 * @default false 24759 */ 24760 "bDrawing": false, 24761 24762 /** 24763 * Draw index (iDraw) of the last error when parsing the returned data 24764 * @type int 24765 * @default -1 24766 */ 24767 "iDrawError": -1, 24768 24769 /** 24770 * Paging display length 24771 * @type int 24772 * @default 10 24773 */ 24774 "_iDisplayLength": 10, 24775 24776 /** 24777 * Paging start point - aiDisplay index 24778 * @type int 24779 * @default 0 24780 */ 24781 "_iDisplayStart": 0, 24782 24783 /** 24784 * Server-side processing - number of records in the result set 24785 * (i.e. before filtering), Use fnRecordsTotal rather than 24786 * this property to get the value of the number of records, regardless of 24787 * the server-side processing setting. 24788 * @type int 24789 * @default 0 24790 * @private 24791 */ 24792 "_iRecordsTotal": 0, 24793 24794 /** 24795 * Server-side processing - number of records in the current display set 24796 * (i.e. after filtering). Use fnRecordsDisplay rather than 24797 * this property to get the value of the number of records, regardless of 24798 * the server-side processing setting. 24799 * @type boolean 24800 * @default 0 24801 * @private 24802 */ 24803 "_iRecordsDisplay": 0, 24804 24805 /** 24806 * The classes to use for the table 24807 * @type object 24808 * @default {} 24809 */ 24810 "oClasses": {}, 24811 24812 /** 24813 * Flag attached to the settings object so you can check in the draw 24814 * callback if filtering has been done in the draw. Deprecated in favour of 24815 * events. 24816 * @type boolean 24817 * @default false 24818 * @deprecated 24819 */ 24820 "bFiltered": false, 24821 24822 /** 24823 * Flag attached to the settings object so you can check in the draw 24824 * callback if sorting has been done in the draw. Deprecated in favour of 24825 * events. 24826 * @type boolean 24827 * @default false 24828 * @deprecated 24829 */ 24830 "bSorted": false, 24831 24832 /** 24833 * Indicate that if multiple rows are in the header and there is more than 24834 * one unique cell per column, if the top one (true) or bottom one (false) 24835 * should be used for sorting / title by DataTables. 24836 * Note that this parameter will be set by the initialisation routine. To 24837 * set a default use {@link DataTable.defaults}. 24838 * @type boolean 24839 */ 24840 "bSortCellsTop": null, 24841 24842 /** 24843 * Initialisation object that is used for the table 24844 * @type object 24845 * @default null 24846 */ 24847 "oInit": null, 24848 24849 /** 24850 * Destroy callback functions - for plug-ins to attach themselves to the 24851 * destroy so they can clean up markup and events. 24852 * @type array 24853 * @default [] 24854 */ 24855 "aoDestroyCallback": [], 24856 24857 24858 /** 24859 * Get the number of records in the current record set, before filtering 24860 * @type function 24861 */ 24862 "fnRecordsTotal": function () 24863 { 24864 return _fnDataSource( this ) == 'ssp' ? 24865 this._iRecordsTotal * 1 : 24866 this.aiDisplayMaster.length; 24867 }, 24868 24869 /** 24870 * Get the number of records in the current record set, after filtering 24871 * @type function 24872 */ 24873 "fnRecordsDisplay": function () 24874 { 24875 return _fnDataSource( this ) == 'ssp' ? 24876 this._iRecordsDisplay * 1 : 24877 this.aiDisplay.length; 24878 }, 24879 24880 /** 24881 * Get the display end point - aiDisplay index 24882 * @type function 24883 */ 24884 "fnDisplayEnd": function () 24885 { 24886 var 24887 len = this._iDisplayLength, 24888 start = this._iDisplayStart, 24889 calc = start + len, 24890 records = this.aiDisplay.length, 24891 features = this.oFeatures, 24892 paginate = features.bPaginate; 24893 24894 if ( features.bServerSide ) { 24895 return paginate === false || len === -1 ? 24896 start + records : 24897 Math.min( start+len, this._iRecordsDisplay ); 24898 } 24899 else { 24900 return ! paginate || calc>records || len===-1 ? 24901 records : 24902 calc; 24903 } 24904 }, 24905 24906 /** 24907 * The DataTables object for this table 24908 * @type object 24909 * @default null 24910 */ 24911 "oInstance": null, 24912 24913 /** 24914 * Unique identifier for each instance of the DataTables object. If there 24915 * is an ID on the table node, then it takes that value, otherwise an 24916 * incrementing internal counter is used. 24917 * @type string 24918 * @default null 24919 */ 24920 "sInstance": null, 24921 24922 /** 24923 * tabindex attribute value that is added to DataTables control elements, allowing 24924 * keyboard navigation of the table and its controls. 24925 */ 24926 "iTabIndex": 0, 24927 24928 /** 24929 * DIV container for the footer scrolling table if scrolling 24930 */ 24931 "nScrollHead": null, 24932 24933 /** 24934 * DIV container for the footer scrolling table if scrolling 24935 */ 24936 "nScrollFoot": null, 24937 24938 /** 24939 * Last applied sort 24940 * @type array 24941 * @default [] 24942 */ 24943 "aLastSort": [], 24944 24945 /** 24946 * Stored plug-in instances 24947 * @type object 24948 * @default {} 24949 */ 24950 "oPlugins": {}, 24951 24952 /** 24953 * Function used to get a row's id from the row's data 24954 * @type function 24955 * @default null 24956 */ 24957 "rowIdFn": null, 24958 24959 /** 24960 * Data location where to store a row's id 24961 * @type string 24962 * @default null 24963 */ 24964 "rowId": null 24965 }; 24966 24967 /** 24968 * Extension object for DataTables that is used to provide all extension 24969 * options. 24970 * 24971 * Note that the `DataTable.ext` object is available through 24972 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is 24973 * also aliased to `jQuery.fn.dataTableExt` for historic reasons. 24974 * @namespace 24975 * @extends DataTable.models.ext 24976 */ 24977 24978 24979 /** 24980 * DataTables extensions 24981 * 24982 * This namespace acts as a collection area for plug-ins that can be used to 24983 * extend DataTables capabilities. Indeed many of the build in methods 24984 * use this method to provide their own capabilities (sorting methods for 24985 * example). 24986 * 24987 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy 24988 * reasons 24989 * 24990 * @namespace 24991 */ 24992 DataTable.ext = _ext = { 24993 /** 24994 * Buttons. For use with the Buttons extension for DataTables. This is 24995 * defined here so other extensions can define buttons regardless of load 24996 * order. It is _not_ used by DataTables core. 24997 * 24998 * @type object 24999 * @default {} 25000 */ 25001 buttons: {}, 25002 25003 25004 /** 25005 * Element class names 25006 * 25007 * @type object 25008 * @default {} 25009 */ 25010 classes: {}, 25011 25012 25013 /** 25014 * DataTables build type (expanded by the download builder) 25015 * 25016 * @type string 25017 */ 25018 builder: "-source-", 25019 25020 25021 /** 25022 * Error reporting. 25023 * 25024 * How should DataTables report an error. Can take the value 'alert', 25025 * 'throw', 'none' or a function. 25026 * 25027 * @type string|function 25028 * @default alert 25029 */ 25030 errMode: "alert", 25031 25032 25033 /** 25034 * Feature plug-ins. 25035 * 25036 * This is an array of objects which describe the feature plug-ins that are 25037 * available to DataTables. These feature plug-ins are then available for 25038 * use through the `dom` initialisation option. 25039 * 25040 * Each feature plug-in is described by an object which must have the 25041 * following properties: 25042 * 25043 * * `fnInit` - function that is used to initialise the plug-in, 25044 * * `cFeature` - a character so the feature can be enabled by the `dom` 25045 * instillation option. This is case sensitive. 25046 * 25047 * The `fnInit` function has the following input parameters: 25048 * 25049 * 1. `{object}` DataTables settings object: see 25050 * {@link DataTable.models.oSettings} 25051 * 25052 * And the following return is expected: 25053 * 25054 * * {node|null} The element which contains your feature. Note that the 25055 * return may also be void if your plug-in does not require to inject any 25056 * DOM elements into DataTables control (`dom`) - for example this might 25057 * be useful when developing a plug-in which allows table control via 25058 * keyboard entry 25059 * 25060 * @type array 25061 * 25062 * @example 25063 * $.fn.dataTable.ext.features.push( { 25064 * "fnInit": function( oSettings ) { 25065 * return new TableTools( { "oDTSettings": oSettings } ); 25066 * }, 25067 * "cFeature": "T" 25068 * } ); 25069 */ 25070 feature: [], 25071 25072 25073 /** 25074 * Row searching. 25075 * 25076 * This method of searching is complimentary to the default type based 25077 * searching, and a lot more comprehensive as it allows you complete control 25078 * over the searching logic. Each element in this array is a function 25079 * (parameters described below) that is called for every row in the table, 25080 * and your logic decides if it should be included in the searching data set 25081 * or not. 25082 * 25083 * Searching functions have the following input parameters: 25084 * 25085 * 1. `{object}` DataTables settings object: see 25086 * {@link DataTable.models.oSettings} 25087 * 2. `{array|object}` Data for the row to be processed (same as the 25088 * original format that was passed in as the data source, or an array 25089 * from a DOM data source 25090 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which 25091 * can be useful to retrieve the `TR` element if you need DOM interaction. 25092 * 25093 * And the following return is expected: 25094 * 25095 * * {boolean} Include the row in the searched result set (true) or not 25096 * (false) 25097 * 25098 * Note that as with the main search ability in DataTables, technically this 25099 * is "filtering", since it is subtractive. However, for consistency in 25100 * naming we call it searching here. 25101 * 25102 * @type array 25103 * @default [] 25104 * 25105 * @example 25106 * // The following example shows custom search being applied to the 25107 * // fourth column (i.e. the data[3] index) based on two input values 25108 * // from the end-user, matching the data in a certain range. 25109 * $.fn.dataTable.ext.search.push( 25110 * function( settings, data, dataIndex ) { 25111 * var min = document.getElementById('min').value * 1; 25112 * var max = document.getElementById('max').value * 1; 25113 * var version = data[3] == "-" ? 0 : data[3]*1; 25114 * 25115 * if ( min == "" && max == "" ) { 25116 * return true; 25117 * } 25118 * else if ( min == "" && version < max ) { 25119 * return true; 25120 * } 25121 * else if ( min < version && "" == max ) { 25122 * return true; 25123 * } 25124 * else if ( min < version && version < max ) { 25125 * return true; 25126 * } 25127 * return false; 25128 * } 25129 * ); 25130 */ 25131 search: [], 25132 25133 25134 /** 25135 * Selector extensions 25136 * 25137 * The `selector` option can be used to extend the options available for the 25138 * selector modifier options (`selector-modifier` object data type) that 25139 * each of the three built in selector types offer (row, column and cell + 25140 * their plural counterparts). For example the Select extension uses this 25141 * mechanism to provide an option to select only rows, columns and cells 25142 * that have been marked as selected by the end user (`{selected: true}`), 25143 * which can be used in conjunction with the existing built in selector 25144 * options. 25145 * 25146 * Each property is an array to which functions can be pushed. The functions 25147 * take three attributes: 25148 * 25149 * * Settings object for the host table 25150 * * Options object (`selector-modifier` object type) 25151 * * Array of selected item indexes 25152 * 25153 * The return is an array of the resulting item indexes after the custom 25154 * selector has been applied. 25155 * 25156 * @type object 25157 */ 25158 selector: { 25159 cell: [], 25160 column: [], 25161 row: [] 25162 }, 25163 25164 25165 /** 25166 * Internal functions, exposed for used in plug-ins. 25167 * 25168 * Please note that you should not need to use the internal methods for 25169 * anything other than a plug-in (and even then, try to avoid if possible). 25170 * The internal function may change between releases. 25171 * 25172 * @type object 25173 * @default {} 25174 */ 25175 internal: {}, 25176 25177 25178 /** 25179 * Legacy configuration options. Enable and disable legacy options that 25180 * are available in DataTables. 25181 * 25182 * @type object 25183 */ 25184 legacy: { 25185 /** 25186 * Enable / disable DataTables 1.9 compatible server-side processing 25187 * requests 25188 * 25189 * @type boolean 25190 * @default null 25191 */ 25192 ajax: null 25193 }, 25194 25195 25196 /** 25197 * Pagination plug-in methods. 25198 * 25199 * Each entry in this object is a function and defines which buttons should 25200 * be shown by the pagination rendering method that is used for the table: 25201 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the 25202 * buttons are displayed in the document, while the functions here tell it 25203 * what buttons to display. This is done by returning an array of button 25204 * descriptions (what each button will do). 25205 * 25206 * Pagination types (the four built in options and any additional plug-in 25207 * options defined here) can be used through the `paginationType` 25208 * initialisation parameter. 25209 * 25210 * The functions defined take two parameters: 25211 * 25212 * 1. `{int} page` The current page index 25213 * 2. `{int} pages` The number of pages in the table 25214 * 25215 * Each function is expected to return an array where each element of the 25216 * array can be one of: 25217 * 25218 * * `first` - Jump to first page when activated 25219 * * `last` - Jump to last page when activated 25220 * * `previous` - Show previous page when activated 25221 * * `next` - Show next page when activated 25222 * * `{int}` - Show page of the index given 25223 * * `{array}` - A nested array containing the above elements to add a 25224 * containing 'DIV' element (might be useful for styling). 25225 * 25226 * Note that DataTables v1.9- used this object slightly differently whereby 25227 * an object with two functions would be defined for each plug-in. That 25228 * ability is still supported by DataTables 1.10+ to provide backwards 25229 * compatibility, but this option of use is now decremented and no longer 25230 * documented in DataTables 1.10+. 25231 * 25232 * @type object 25233 * @default {} 25234 * 25235 * @example 25236 * // Show previous, next and current page buttons only 25237 * $.fn.dataTableExt.oPagination.current = function ( page, pages ) { 25238 * return [ 'previous', page, 'next' ]; 25239 * }; 25240 */ 25241 pager: {}, 25242 25243 25244 renderer: { 25245 pageButton: {}, 25246 header: {} 25247 }, 25248 25249 25250 /** 25251 * Ordering plug-ins - custom data source 25252 * 25253 * The extension options for ordering of data available here is complimentary 25254 * to the default type based ordering that DataTables typically uses. It 25255 * allows much greater control over the the data that is being used to 25256 * order a column, but is necessarily therefore more complex. 25257 * 25258 * This type of ordering is useful if you want to do ordering based on data 25259 * live from the DOM (for example the contents of an 'input' element) rather 25260 * than just the static string that DataTables knows of. 25261 * 25262 * The way these plug-ins work is that you create an array of the values you 25263 * wish to be ordering for the column in question and then return that 25264 * array. The data in the array much be in the index order of the rows in 25265 * the table (not the currently ordering order!). Which order data gathering 25266 * function is run here depends on the `dt-init columns.orderDataType` 25267 * parameter that is used for the column (if any). 25268 * 25269 * The functions defined take two parameters: 25270 * 25271 * 1. `{object}` DataTables settings object: see 25272 * {@link DataTable.models.oSettings} 25273 * 2. `{int}` Target column index 25274 * 25275 * Each function is expected to return an array: 25276 * 25277 * * `{array}` Data for the column to be ordering upon 25278 * 25279 * @type array 25280 * 25281 * @example 25282 * // Ordering using `input` node values 25283 * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col ) 25284 * { 25285 * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { 25286 * return $('input', td).val(); 25287 * } ); 25288 * } 25289 */ 25290 order: {}, 25291 25292 25293 /** 25294 * Type based plug-ins. 25295 * 25296 * Each column in DataTables has a type assigned to it, either by automatic 25297 * detection or by direct assignment using the `type` option for the column. 25298 * The type of a column will effect how it is ordering and search (plug-ins 25299 * can also make use of the column type if required). 25300 * 25301 * @namespace 25302 */ 25303 type: { 25304 /** 25305 * Type detection functions. 25306 * 25307 * The functions defined in this object are used to automatically detect 25308 * a column's type, making initialisation of DataTables super easy, even 25309 * when complex data is in the table. 25310 * 25311 * The functions defined take two parameters: 25312 * 25313 * 1. `{*}` Data from the column cell to be analysed 25314 * 2. `{settings}` DataTables settings object. This can be used to 25315 * perform context specific type detection - for example detection 25316 * based on language settings such as using a comma for a decimal 25317 * place. Generally speaking the options from the settings will not 25318 * be required 25319 * 25320 * Each function is expected to return: 25321 * 25322 * * `{string|null}` Data type detected, or null if unknown (and thus 25323 * pass it on to the other type detection functions. 25324 * 25325 * @type array 25326 * 25327 * @example 25328 * // Currency type detection plug-in: 25329 * $.fn.dataTable.ext.type.detect.push( 25330 * function ( data, settings ) { 25331 * // Check the numeric part 25332 * if ( ! data.substring(1).match(/[0-9]/) ) { 25333 * return null; 25334 * } 25335 * 25336 * // Check prefixed by currency 25337 * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) { 25338 * return 'currency'; 25339 * } 25340 * return null; 25341 * } 25342 * ); 25343 */ 25344 detect: [], 25345 25346 25347 /** 25348 * Type based search formatting. 25349 * 25350 * The type based searching functions can be used to pre-format the 25351 * data to be search on. For example, it can be used to strip HTML 25352 * tags or to de-format telephone numbers for numeric only searching. 25353 * 25354 * Note that is a search is not defined for a column of a given type, 25355 * no search formatting will be performed. 25356 * 25357 * Pre-processing of searching data plug-ins - When you assign the sType 25358 * for a column (or have it automatically detected for you by DataTables 25359 * or a type detection plug-in), you will typically be using this for 25360 * custom sorting, but it can also be used to provide custom searching 25361 * by allowing you to pre-processing the data and returning the data in 25362 * the format that should be searched upon. This is done by adding 25363 * functions this object with a parameter name which matches the sType 25364 * for that target column. This is the corollary of <i>afnSortData</i> 25365 * for searching data. 25366 * 25367 * The functions defined take a single parameter: 25368 * 25369 * 1. `{*}` Data from the column cell to be prepared for searching 25370 * 25371 * Each function is expected to return: 25372 * 25373 * * `{string|null}` Formatted string that will be used for the searching. 25374 * 25375 * @type object 25376 * @default {} 25377 * 25378 * @example 25379 * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) { 25380 * return d.replace(/\n/g," ").replace( /<.*?>/g, "" ); 25381 * } 25382 */ 25383 search: {}, 25384 25385 25386 /** 25387 * Type based ordering. 25388 * 25389 * The column type tells DataTables what ordering to apply to the table 25390 * when a column is sorted upon. The order for each type that is defined, 25391 * is defined by the functions available in this object. 25392 * 25393 * Each ordering option can be described by three properties added to 25394 * this object: 25395 * 25396 * * `{type}-pre` - Pre-formatting function 25397 * * `{type}-asc` - Ascending order function 25398 * * `{type}-desc` - Descending order function 25399 * 25400 * All three can be used together, only `{type}-pre` or only 25401 * `{type}-asc` and `{type}-desc` together. It is generally recommended 25402 * that only `{type}-pre` is used, as this provides the optimal 25403 * implementation in terms of speed, although the others are provided 25404 * for compatibility with existing Javascript sort functions. 25405 * 25406 * `{type}-pre`: Functions defined take a single parameter: 25407 * 25408 * 1. `{*}` Data from the column cell to be prepared for ordering 25409 * 25410 * And return: 25411 * 25412 * * `{*}` Data to be sorted upon 25413 * 25414 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort 25415 * functions, taking two parameters: 25416 * 25417 * 1. `{*}` Data to compare to the second parameter 25418 * 2. `{*}` Data to compare to the first parameter 25419 * 25420 * And returning: 25421 * 25422 * * `{*}` Ordering match: <0 if first parameter should be sorted lower 25423 * than the second parameter, ===0 if the two parameters are equal and 25424 * >0 if the first parameter should be sorted height than the second 25425 * parameter. 25426 * 25427 * @type object 25428 * @default {} 25429 * 25430 * @example 25431 * // Numeric ordering of formatted numbers with a pre-formatter 25432 * $.extend( $.fn.dataTable.ext.type.order, { 25433 * "string-pre": function(x) { 25434 * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" ); 25435 * return parseFloat( a ); 25436 * } 25437 * } ); 25438 * 25439 * @example 25440 * // Case-sensitive string ordering, with no pre-formatting method 25441 * $.extend( $.fn.dataTable.ext.order, { 25442 * "string-case-asc": function(x,y) { 25443 * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 25444 * }, 25445 * "string-case-desc": function(x,y) { 25446 * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 25447 * } 25448 * } ); 25449 */ 25450 order: {} 25451 }, 25452 25453 /** 25454 * Unique DataTables instance counter 25455 * 25456 * @type int 25457 * @private 25458 */ 25459 _unique: 0, 25460 25461 25462 // 25463 // Depreciated 25464 // The following properties are retained for backwards compatibility only. 25465 // The should not be used in new projects and will be removed in a future 25466 // version 25467 // 25468 25469 /** 25470 * Version check function. 25471 * @type function 25472 * @depreciated Since 1.10 25473 */ 25474 fnVersionCheck: DataTable.fnVersionCheck, 25475 25476 25477 /** 25478 * Index for what 'this' index API functions should use 25479 * @type int 25480 * @deprecated Since v1.10 25481 */ 25482 iApiIndex: 0, 25483 25484 25485 /** 25486 * jQuery UI class container 25487 * @type object 25488 * @deprecated Since v1.10 25489 */ 25490 oJUIClasses: {}, 25491 25492 25493 /** 25494 * Software version 25495 * @type string 25496 * @deprecated Since v1.10 25497 */ 25498 sVersion: DataTable.version 25499 }; 25500 25501 25502 // 25503 // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts 25504 // 25505 $.extend( _ext, { 25506 afnFiltering: _ext.search, 25507 aTypes: _ext.type.detect, 25508 ofnSearch: _ext.type.search, 25509 oSort: _ext.type.order, 25510 afnSortData: _ext.order, 25511 aoFeatures: _ext.feature, 25512 oApi: _ext.internal, 25513 oStdClasses: _ext.classes, 25514 oPagination: _ext.pager 25515 } ); 25516 25517 25518 $.extend( DataTable.ext.classes, { 25519 "sTable": "dataTable", 25520 "sNoFooter": "no-footer", 25521 25522 /* Paging buttons */ 25523 "sPageButton": "paginate_button", 25524 "sPageButtonActive": "current", 25525 "sPageButtonDisabled": "disabled", 25526 25527 /* Striping classes */ 25528 "sStripeOdd": "odd", 25529 "sStripeEven": "even", 25530 25531 /* Empty row */ 25532 "sRowEmpty": "dataTables_empty", 25533 25534 /* Features */ 25535 "sWrapper": "dataTables_wrapper", 25536 "sFilter": "dataTables_filter", 25537 "sInfo": "dataTables_info", 25538 "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ 25539 "sLength": "dataTables_length", 25540 "sProcessing": "dataTables_processing", 25541 25542 /* Sorting */ 25543 "sSortAsc": "sorting_asc", 25544 "sSortDesc": "sorting_desc", 25545 "sSortable": "sorting", /* Sortable in both directions */ 25546 "sSortableAsc": "sorting_desc_disabled", 25547 "sSortableDesc": "sorting_asc_disabled", 25548 "sSortableNone": "sorting_disabled", 25549 "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ 25550 25551 /* Filtering */ 25552 "sFilterInput": "", 25553 25554 /* Page length */ 25555 "sLengthSelect": "", 25556 25557 /* Scrolling */ 25558 "sScrollWrapper": "dataTables_scroll", 25559 "sScrollHead": "dataTables_scrollHead", 25560 "sScrollHeadInner": "dataTables_scrollHeadInner", 25561 "sScrollBody": "dataTables_scrollBody", 25562 "sScrollFoot": "dataTables_scrollFoot", 25563 "sScrollFootInner": "dataTables_scrollFootInner", 25564 25565 /* Misc */ 25566 "sHeaderTH": "", 25567 "sFooterTH": "", 25568 25569 // Deprecated 25570 "sSortJUIAsc": "", 25571 "sSortJUIDesc": "", 25572 "sSortJUI": "", 25573 "sSortJUIAscAllowed": "", 25574 "sSortJUIDescAllowed": "", 25575 "sSortJUIWrapper": "", 25576 "sSortIcon": "", 25577 "sJUIHeader": "", 25578 "sJUIFooter": "" 25579 } ); 25580 25581 25582 var extPagination = DataTable.ext.pager; 25583 25584 function _numbers ( page, pages ) { 25585 var 25586 numbers = [], 25587 buttons = extPagination.numbers_length, 25588 half = Math.floor( buttons / 2 ), 25589 i = 1; 25590 25591 if ( pages <= buttons ) { 25592 numbers = _range( 0, pages ); 25593 } 25594 else if ( page <= half ) { 25595 numbers = _range( 0, buttons-2 ); 25596 numbers.push( 'ellipsis' ); 25597 numbers.push( pages-1 ); 25598 } 25599 else if ( page >= pages - 1 - half ) { 25600 numbers = _range( pages-(buttons-2), pages ); 25601 numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6 25602 numbers.splice( 0, 0, 0 ); 25603 } 25604 else { 25605 numbers = _range( page-half+2, page+half-1 ); 25606 numbers.push( 'ellipsis' ); 25607 numbers.push( pages-1 ); 25608 numbers.splice( 0, 0, 'ellipsis' ); 25609 numbers.splice( 0, 0, 0 ); 25610 } 25611 25612 numbers.DT_el = 'span'; 25613 return numbers; 25614 } 25615 25616 25617 $.extend( extPagination, { 25618 simple: function ( page, pages ) { 25619 return [ 'previous', 'next' ]; 25620 }, 25621 25622 full: function ( page, pages ) { 25623 return [ 'first', 'previous', 'next', 'last' ]; 25624 }, 25625 25626 numbers: function ( page, pages ) { 25627 return [ _numbers(page, pages) ]; 25628 }, 25629 25630 simple_numbers: function ( page, pages ) { 25631 return [ 'previous', _numbers(page, pages), 'next' ]; 25632 }, 25633 25634 full_numbers: function ( page, pages ) { 25635 return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ]; 25636 }, 25637 25638 first_last_numbers: function (page, pages) { 25639 return ['first', _numbers(page, pages), 'last']; 25640 }, 25641 25642 // For testing and plug-ins to use 25643 _numbers: _numbers, 25644 25645 // Number of number buttons (including ellipsis) to show. _Must be odd!_ 25646 numbers_length: 7 25647 } ); 25648 25649 25650 $.extend( true, DataTable.ext.renderer, { 25651 pageButton: { 25652 _: function ( settings, host, idx, buttons, page, pages ) { 25653 var classes = settings.oClasses; 25654 var lang = settings.oLanguage.oPaginate; 25655 var aria = settings.oLanguage.oAria.paginate || {}; 25656 var btnDisplay, btnClass
vendor: 17,892 bytes, lines 25656-26294
25656, counter=0; 25657 25658 var attach = function( container, buttons ) { 25659 var i, ien, node, button, tabIndex; 25660 var disabledClass = classes.sPageButtonDisabled; 25661 var clickHandler = function ( e ) { 25662 _fnPageChange( settings, e.data.action, true ); 25663 }; 25664 25665 for ( i=0, ien=buttons.length ; i<ien ; i++ ) { 25666 button = buttons[i]; 25667 25668 if ( Array.isArray( button ) ) { 25669 var inner = $( '<'+(button.DT_el || 'div')+'/>' ) 25670 .appendTo( container ); 25671 attach( inner, button ); 25672 } 25673 else { 25674 btnDisplay = null; 25675 btnClass = button; 25676 tabIndex = settings.iTabIndex; 25677 25678 switch ( button ) { 25679 case 'ellipsis': 25680 container.append('<span class="ellipsis">…</span>'); 25681 break; 25682 25683 case 'first': 25684 btnDisplay = lang.sFirst; 25685 25686 if ( page === 0 ) { 25687 tabIndex = -1; 25688 btnClass += ' ' + disabledClass; 25689 } 25690 break; 25691 25692 case 'previous': 25693 btnDisplay = lang.sPrevious; 25694 25695 if ( page === 0 ) { 25696 tabIndex = -1; 25697 btnClass += ' ' + disabledClass; 25698 } 25699 break; 25700 25701 case 'next': 25702 btnDisplay = lang.sNext; 25703 25704 if ( pages === 0 || page === pages-1 ) { 25705 tabIndex = -1; 25706 btnClass += ' ' + disabledClass; 25707 } 25708 break; 25709 25710 case 'last': 25711 btnDisplay = lang.sLast; 25712 25713 if ( pages === 0 || page === pages-1 ) { 25714 tabIndex = -1; 25715 btnClass += ' ' + disabledClass; 25716 } 25717 break; 25718 25719 default: 25720 btnDisplay = settings.fnFormatNumber( button + 1 ); 25721 btnClass = page === button ? 25722 classes.sPageButtonActive : ''; 25723 break; 25724 } 25725 25726 if ( btnDisplay !== null ) { 25727 node = $('<a>', { 25728 'class': classes.sPageButton+' '+btnClass, 25729 'aria-controls': settings.sTableId, 25730 'aria-label': aria[ button ], 25731 'data-dt-idx': counter, 25732 'tabindex': tabIndex, 25733 'id': idx === 0 && typeof button === 'string' ? 25734 settings.sTableId +'_'+ button : 25735 null 25736 } ) 25737 .html( btnDisplay ) 25738 .appendTo( container ); 25739 25740 _fnBindAction( 25741 node, {action: button}, clickHandler 25742 ); 25743 25744 counter++; 25745 } 25746 } 25747 } 25748 }; 25749 25750 // IE9 throws an 'unknown error' if document.activeElement is used 25751 // inside an iframe or frame. Try / catch the error. Not good for 25752 // accessibility, but neither are frames. 25753 var activeEl; 25754 25755 try { 25756 // Because this approach is destroying and recreating the paging 25757 // elements, focus is lost on the select button which is bad for 25758 // accessibility. So we want to restore focus once the draw has 25759 // completed 25760 activeEl = $(host).find(document.activeElement).data('dt-idx'); 25761 } 25762 catch (e) {} 25763 25764 attach( $(host).empty(), buttons ); 25765 25766 if ( activeEl !== undefined ) { 25767 $(host).find( '[data-dt-idx='+activeEl+']' ).trigger('focus'); 25768 } 25769 } 25770 } 25771 } ); 25772 25773 25774 25775 // Built in type detection. See model.ext.aTypes for information about 25776 // what is required from this methods. 25777 $.extend( DataTable.ext.type.detect, [ 25778 // Plain numbers - first since V8 detects some plain numbers as dates 25779 // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...). 25780 function ( d, settings ) 25781 { 25782 var decimal = settings.oLanguage.sDecimal; 25783 return _isNumber( d, decimal ) ? 'num'+decimal : null; 25784 }, 25785 25786 // Dates (only those recognised by the browser's Date.parse) 25787 function ( d, settings ) 25788 { 25789 // V8 tries _very_ hard to make a string passed into `Date.parse()` 25790 // valid, so we need to use a regex to restrict date formats. Use a 25791 // plug-in for anything other than ISO8601 style strings 25792 if ( d && !(d instanceof Date) && ! _re_date.test(d) ) { 25793 return null; 25794 } 25795 var parsed = Date.parse(d); 25796 return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null; 25797 }, 25798 25799 // Formatted numbers 25800 function ( d, settings ) 25801 { 25802 var decimal = settings.oLanguage.sDecimal; 25803 return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null; 25804 }, 25805 25806 // HTML numeric 25807 function ( d, settings ) 25808 { 25809 var decimal = settings.oLanguage.sDecimal; 25810 return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null; 25811 }, 25812 25813 // HTML numeric, formatted 25814 function ( d, settings ) 25815 { 25816 var decimal = settings.oLanguage.sDecimal; 25817 return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null; 25818 }, 25819 25820 // HTML (this is strict checking - there must be html) 25821 function ( d, settings ) 25822 { 25823 return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ? 25824 'html' : null; 25825 } 25826 ] ); 25827 25828 25829 25830 // Filter formatting functions. See model.ext.ofnSearch for information about 25831 // what is required from these methods. 25832 // 25833 // Note that additional search methods are added for the html numbers and 25834 // html formatted numbers by `_addNumericSort()` when we know what the decimal 25835 // place is 25836 25837 25838 $.extend( DataTable.ext.type.search, { 25839 html: function ( data ) { 25840 return _empty(data) ? 25841 data : 25842 typeof data === 'string' ? 25843 data 25844 .replace( _re_new_lines, " " ) 25845 .replace( _re_html, "" ) : 25846 ''; 25847 }, 25848 25849 string: function ( data ) { 25850 return _empty(data) ? 25851 data : 25852 typeof data === 'string' ? 25853 data.replace( _re_new_lines, " " ) : 25854 data; 25855 } 25856 } ); 25857 25858 25859 25860 var __numericReplace = function ( d, decimalPlace, re1, re2 ) { 25861 if ( d !== 0 && (!d || d === '-') ) { 25862 return -Infinity; 25863 } 25864 25865 // If a decimal place other than `.` is used, it needs to be given to the 25866 // function so we can detect it and replace with a `.` which is the only 25867 // decimal place Javascript recognises - it is not locale aware. 25868 if ( decimalPlace ) { 25869 d = _numToDecimal( d, decimalPlace ); 25870 } 25871 25872 if ( d.replace ) { 25873 if ( re1 ) { 25874 d = d.replace( re1, '' ); 25875 } 25876 25877 if ( re2 ) { 25878 d = d.replace( re2, '' ); 25879 } 25880 } 25881 25882 return d * 1; 25883 }; 25884 25885 25886 // Add the numeric 'deformatting' functions for sorting and search. This is done 25887 // in a function to provide an easy ability for the language options to add 25888 // additional methods if a non-period decimal place is used. 25889 function _addNumericSort ( decimalPlace ) { 25890 $.each( 25891 { 25892 // Plain numbers 25893 "num": function ( d ) { 25894 return __numericReplace( d, decimalPlace ); 25895 }, 25896 25897 // Formatted numbers 25898 "num-fmt": function ( d ) { 25899 return __numericReplace( d, decimalPlace, _re_formatted_numeric ); 25900 }, 25901 25902 // HTML numeric 25903 "html-num": function ( d ) { 25904 return __numericReplace( d, decimalPlace, _re_html ); 25905 }, 25906 25907 // HTML numeric, formatted 25908 "html-num-fmt": function ( d ) { 25909 return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric ); 25910 } 25911 }, 25912 function ( key, fn ) { 25913 // Add the ordering method 25914 _ext.type.order[ key+decimalPlace+'-pre' ] = fn; 25915 25916 // For HTML types add a search formatter that will strip the HTML 25917 if ( key.match(/^html\-/) ) { 25918 _ext.type.search[ key+decimalPlace ] = _ext.type.search.html; 25919 } 25920 } 25921 ); 25922 } 25923 25924 25925 // Default sort methods 25926 $.extend( _ext.type.order, { 25927 // Dates 25928 "date-pre": function ( d ) { 25929 var ts = Date.parse( d ); 25930 return isNaN(ts) ? -Infinity : ts; 25931 }, 25932 25933 // html 25934 "html-pre": function ( a ) { 25935 return _empty(a) ? 25936 '' : 25937 a.replace ? 25938 a.replace( /<.*?>/g, "" ).toLowerCase() : 25939 a+''; 25940 }, 25941 25942 // string 25943 "string-pre": function ( a ) { 25944 // This is a little complex, but faster than always calling toString, 25945 // http://jsperf.com/tostring-v-check 25946 return _empty(a) ? 25947 '' : 25948 typeof a === 'string' ? 25949 a.toLowerCase() : 25950 ! a.toString ? 25951 '' : 25952 a.toString(); 25953 }, 25954 25955 // string-asc and -desc are retained only for compatibility with the old 25956 // sort methods 25957 "string-asc": function ( x, y ) { 25958 return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 25959 }, 25960 25961 "string-desc": function ( x, y ) { 25962 return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 25963 } 25964 } ); 25965 25966 25967 // Numeric sorting types - order doesn't matter here 25968 _addNumericSort( '' ); 25969 25970 25971 $.extend( true, DataTable.ext.renderer, { 25972 header: { 25973 _: function ( settings, cell, column, classes ) { 25974 // No additional mark-up required 25975 // Attach a sort listener to update on sort - note that using the 25976 // `DT` namespace will allow the event to be removed automatically 25977 // on destroy, while the `dt` namespaced event is the one we are 25978 // listening for 25979 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { 25980 if ( settings !== ctx ) { // need to check this this is the host 25981 return; // table, not a nested one 25982 } 25983 25984 var colIdx = column.idx; 25985 25986 cell 25987 .removeClass( 25988 classes.sSortAsc +' '+ 25989 classes.sSortDesc 25990 ) 25991 .addClass( columns[ colIdx ] == 'asc' ? 25992 classes.sSortAsc : columns[ colIdx ] == 'desc' ? 25993 classes.sSortDesc : 25994 column.sSortingClass 25995 ); 25996 } ); 25997 }, 25998 25999 jqueryui: function ( settings, cell, column, classes ) { 26000 $('<div/>') 26001 .addClass( classes.sSortJUIWrapper ) 26002 .append( cell.contents() ) 26003 .append( $('<span/>') 26004 .addClass( classes.sSortIcon+' '+column.sSortingClassJUI ) 26005 ) 26006 .appendTo( cell ); 26007 26008 // Attach a sort listener to update on sort 26009 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) { 26010 if ( settings !== ctx ) { 26011 return; 26012 } 26013 26014 var colIdx = column.idx; 26015 26016 cell 26017 .removeClass( classes.sSortAsc +" "+classes.sSortDesc ) 26018 .addClass( columns[ colIdx ] == 'asc' ? 26019 classes.sSortAsc : columns[ colIdx ] == 'desc' ? 26020 classes.sSortDesc : 26021 column.sSortingClass 26022 ); 26023 26024 cell 26025 .find( 'span.'+classes.sSortIcon ) 26026 .removeClass( 26027 classes.sSortJUIAsc +" "+ 26028 classes.sSortJUIDesc +" "+ 26029 classes.sSortJUI +" "+ 26030 classes.sSortJUIAscAllowed +" "+ 26031 classes.sSortJUIDescAllowed 26032 ) 26033 .addClass( columns[ colIdx ] == 'asc' ? 26034 classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ? 26035 classes.sSortJUIDesc : 26036 column.sSortingClassJUI 26037 ); 26038 } ); 26039 } 26040 } 26041 } ); 26042 26043 /* 26044 * Public helper functions. These aren't used internally by DataTables, or 26045 * called by any of the options passed into DataTables, but they can be used 26046 * externally by developers working with DataTables. They are helper functions 26047 * to make working with DataTables a little bit easier. 26048 */ 26049 26050 var __htmlEscapeEntities = function ( d ) { 26051 if (Array.isArray(d)) { 26052 d = d.join(','); 26053 } 26054 26055 return typeof d === 'string' ? 26056 d 26057 .replace(/&/g, '&') 26058 .replace(/</g, '<') 26059 .replace(/>/g, '>') 26060 .replace(/"/g, '"') : 26061 d; 26062 }; 26063 26064 /** 26065 * Helpers for `columns.render`. 26066 * 26067 * The options defined here can be used with the `columns.render` initialisation 26068 * option to provide a display renderer. The following functions are defined: 26069 * 26070 * * `number` - Will format numeric data (defined by `columns.data`) for 26071 * display, retaining the original unformatted data for sorting and filtering. 26072 * It takes 5 parameters: 26073 * * `string` - Thousands grouping separator 26074 * * `string` - Decimal point indicator 26075 * * `integer` - Number of decimal points to show 26076 * * `string` (optional) - Prefix. 26077 * * `string` (optional) - Postfix (/suffix). 26078 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional 26079 * parameters. 26080 * 26081 * @example 26082 * // Column definition using the number renderer 26083 * { 26084 * data: "salary", 26085 * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' ) 26086 * } 26087 * 26088 * @namespace 26089 */ 26090 DataTable.render = { 26091 number: function ( thousands, decimal, precision, prefix, postfix ) { 26092 return { 26093 display: function ( d ) { 26094 if ( typeof d !== 'number' && typeof d !== 'string' ) { 26095 return d; 26096 } 26097 26098 var negative = d < 0 ? '-' : ''; 26099 var flo = parseFloat( d ); 26100 26101 // If NaN then there isn't much formatting that we can do - just 26102 // return immediately, escaping any HTML (this was supposed to 26103 // be a number after all) 26104 if ( isNaN( flo ) ) { 26105 return __htmlEscapeEntities( d ); 26106 } 26107 26108 flo = flo.toFixed( precision ); 26109 d = Math.abs( flo ); 26110 26111 var intPart = parseInt( d, 10 ); 26112 var floatPart = precision ? 26113 decimal+(d - intPart).toFixed( precision ).substring( 2 ): 26114 ''; 26115 26116 // If zero, then can't have a negative prefix 26117 if (intPart === 0 && parseFloat(floatPart) === 0) { 26118 negative = ''; 26119 } 26120 26121 return negative + (prefix||'') + 26122 intPart.toString().replace( 26123 /\B(?=(\d{3})+(?!\d))/g, thousands 26124 ) + 26125 floatPart + 26126 (postfix||''); 26127 } 26128 }; 26129 }, 26130 26131 text: function () { 26132 return { 26133 display: __htmlEscapeEntities, 26134 filter: __htmlEscapeEntities 26135 }; 26136 } 26137 }; 26138 26139 26140 /* 26141 * This is really a good bit rubbish this method of exposing the internal methods 26142 * publicly... - To be fixed in 2.0 using methods on the prototype 26143 */ 26144 26145 26146 /** 26147 * Create a wrapper function for exporting an internal functions to an external API. 26148 * @param {string} fn API function name 26149 * @returns {function} wrapped function 26150 * @memberof DataTable#internal 26151 */ 26152 function _fnExternApiFunc (fn) 26153 { 26154 return function() { 26155 var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat( 26156 Array.prototype.slice.call(arguments) 26157 ); 26158 return DataTable.ext.internal[fn].apply( this, args ); 26159 }; 26160 } 26161 26162 26163 /** 26164 * Reference to internal functions for use by plug-in developers. Note that 26165 * these methods are references to internal functions and are considered to be 26166 * private. If you use these methods, be aware that they are liable to change 26167 * between versions. 26168 * @namespace 26169 */ 26170 $.extend( DataTable.ext.internal, { 26171 _fnExternApiFunc: _fnExternApiFunc, 26172 _fnBuildAjax: _fnBuildAjax, 26173 _fnAjaxUpdate: _fnAjaxUpdate, 26174 _fnAjaxParameters: _fnAjaxParameters, 26175 _fnAjaxUpdateDraw: _fnAjaxUpdateDraw, 26176 _fnAjaxDataSrc: _fnAjaxDataSrc, 26177 _fnAddColumn: _fnAddColumn, 26178 _fnColumnOptions: _fnColumnOptions, 26179 _fnAdjustColumnSizing: _fnAdjustColumnSizing, 26180 _fnVisibleToColumnIndex: _fnVisibleToColumnIndex, 26181 _fnColumnIndexToVisible: _fnColumnIndexToVisible, 26182 _fnVisbleColumns: _fnVisbleColumns, 26183 _fnGetColumns: _fnGetColumns, 26184 _fnColumnTypes: _fnColumnTypes, 26185 _fnApplyColumnDefs: _fnApplyColumnDefs, 26186 _fnHungarianMap: _fnHungarianMap, 26187 _fnCamelToHungarian: _fnCamelToHungarian, 26188 _fnLanguageCompat: _fnLanguageCompat, 26189 _fnBrowserDetect: _fnBrowserDetect, 26190 _fnAddData: _fnAddData, 26191 _fnAddTr: _fnAddTr, 26192 _fnNodeToDataIndex: _fnNodeToDataIndex, 26193 _fnNodeToColumnIndex: _fnNodeToColumnIndex, 26194 _fnGetCellData: _fnGetCellData, 26195 _fnSetCellData: _fnSetCellData, 26196 _fnSplitObjNotation: _fnSplitObjNotation, 26197 _fnGetObjectDataFn: _fnGetObjectDataFn, 26198 _fnSetObjectDataFn: _fnSetObjectDataFn, 26199 _fnGetDataMaster: _fnGetDataMaster, 26200 _fnClearTable: _fnClearTable, 26201 _fnDeleteIndex: _fnDeleteIndex, 26202 _fnInvalidate: _fnInvalidate, 26203 _fnGetRowElements: _fnGetRowElements, 26204 _fnCreateTr: _fnCreateTr, 26205 _fnBuildHead: _fnBuildHead, 26206 _fnDrawHead: _fnDrawHead, 26207 _fnDraw: _fnDraw, 26208 _fnReDraw: _fnReDraw, 26209 _fnAddOptionsHtml: _fnAddOptionsHtml, 26210 _fnDetectHeader: _fnDetectHeader, 26211 _fnGetUniqueThs: _fnGetUniqueThs, 26212 _fnFeatureHtmlFilter: _fnFeatureHtmlFilter, 26213 _fnFilterComplete: _fnFilterComplete, 26214 _fnFilterCustom: _fnFilterCustom, 26215 _fnFilterColumn: _fnFilterColumn, 26216 _fnFilter: _fnFilter, 26217 _fnFilterCreateSearch: _fnFilterCreateSearch, 26218 _fnEscapeRegex: _fnEscapeRegex, 26219 _fnFilterData: _fnFilterData, 26220 _fnFeatureHtmlInfo: _fnFeatureHtmlInfo, 26221 _fnUpdateInfo: _fnUpdateInfo, 26222 _fnInfoMacros: _fnInfoMacros, 26223 _fnInitialise: _fnInitialise, 26224 _fnInitComplete: _fnInitComplete, 26225 _fnLengthChange: _fnLengthChange, 26226 _fnFeatureHtmlLength: _fnFeatureHtmlLength, 26227 _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate, 26228 _fnPageChange: _fnPageChange, 26229 _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing, 26230 _fnProcessingDisplay: _fnProcessingDisplay, 26231 _fnFeatureHtmlTable: _fnFeatureHtmlTable, 26232 _fnScrollDraw: _fnScrollDraw, 26233 _fnApplyToChildren: _fnApplyToChildren, 26234 _fnCalculateColumnWidths: _fnCalculateColumnWidths, 26235 _fnThrottle: _fnThrottle, 26236 _fnConvertToWidth: _fnConvertToWidth, 26237 _fnGetWidestNode: _fnGetWidestNode, 26238 _fnGetMaxLenString: _fnGetMaxLenString, 26239 _fnStringToCss: _fnStringToCss, 26240 _fnSortFlatten: _fnSortFlatten, 26241 _fnSort: _fnSort, 26242 _fnSortAria: _fnSortAria, 26243 _fnSortListener: _fnSortListener, 26244 _fnSortAttachListener: _fnSortAttachListener, 26245 _fnSortingClasses: _fnSortingClasses, 26246 _fnSortData: _fnSortData, 26247 _fnSaveState: _fnSaveState, 26248 _fnLoadState: _fnLoadState, 26249 _fnImplementState: _fnImplementState, 26250 _fnSettingsFromNode: _fnSettingsFromNode, 26251 _fnLog: _fnLog, 26252 _fnMap: _fnMap, 26253 _fnBindAction: _fnBindAction, 26254 _fnCallbackReg: _fnCallbackReg, 26255 _fnCallbackFire: _fnCallbackFire, 26256 _fnLengthOverflow: _fnLengthOverflow, 26257 _fnRenderer: _fnRenderer, 26258 _fnDataSource: _fnDataSource, 26259 _fnRowAttributes: _fnRowAttributes, 26260 _fnExtend: _fnExtend, 26261 _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant 26262 // in 1.10, so this dead-end function is 26263 // added to prevent errors 26264 } ); 26265 26266 26267 // jQuery access 26268 $.fn.dataTable = DataTable; 26269 26270 // Provide access to the host jQuery object (circular reference) 26271 DataTable.$ = $; 26272 26273 // Legacy aliases 26274 $.fn.dataTableSettings = DataTable.settings; 26275 $.fn.dataTableExt = DataTable.ext; 26276 26277 // With a capital `D` we return a DataTables API instance rather than a 26278 // jQuery object 26279 $.fn.DataTable = function ( opts ) { 26280 return $(this).dataTable( opts ).api(); 26281 }; 26282 26283 // All properties that are available to $.fn.dataTable should also be 26284 // available on $.fn.DataTable 26285 $.each( DataTable, function ( prop, val ) { 26286 $.fn.DataTable[ prop ] = val; 26287 } ); 26288 26289 return DataTable; 26290})); 26291 26292 26293/***/ }), 26294/* 2 */
vendor: 16,174 bytes, lines 26295-26323
26295/***/ (function(module, exports) { 26296 26297var g; 26298 26299// This works in non-strict mode 26300g = (function() { 26301 return this; 26302})(); 26303 26304try { 26305 // This works if eval is allowed (see CSP) 26306 g = g || new Function("return this")(); 26307} catch (e) { 26308 // This works if the window reference is available 26309 if (typeof window === "object") g = window; 26310} 26311 26312// g can still be undefined, but nothing to do about it... 26313// We return undefined, instead of nothing here, so it's 26314// easier to handle this case. if(!global) { ...} 26315 26316module.exports = g; 26317 26318 26319/***/ }), 26320/* 3 */ 26321/***/ (function(module, exports, __webpack_require__) { 26322 26323!function(e,t){ true?module.exports=t():undefined}(window,(function(){return function(e){var t={};function n(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(a,r,function(t){return e[t]}.bind(null,r));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);var a=[],r=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],i=["January","February","March","April","May","June","July","August","September","October","November","December"],o={t:"top",r:"right",b:"bottom",l:"left",c:"centered"};function s(){}var l=["click","focusin","keydown","input"];function d(e){l.forEach((function(t){e.addEventListener(t,e===document?L:Y)}))}function c(e){return Array.isArray(e)?e.map(c):"[object Object]"===x(e)?Object.keys(e).reduce((function(t,n){return t[n]=c(e[n]),t}),{}):e}function u(e,t){var n=e.calendar.querySelector(".qs-overlay"),a=n&&!n.classList.contains("qs-hidden");t=t||new Date(e.currentYear,e.currentMonth),e.calendar.innerHTML=[h(t,e,a),f(t,e,a),v(e,a)].join(""),a&&window.requestAnimationFrame((function(){M(!0,e)}))}function h(e,t,n){return['<div class="qs-controls'+(n?" qs-blur":"")+'">','<div class="qs-arrow qs-left"></div>','<div class="qs-month-year">','<span class="qs-month">'+t.months[e.getMonth()]+"</span>",'<span class="qs-year">'+e.getFullYear()+"</span>","</div>",'<div class="qs-arrow qs-right"></div>',"</div>"].join("")}function f(e,t,n){var a=t.currentMonth,r=t.currentYear,i=t.dateSelected,o=t.maxDate,s=t.minDate,l=t.showAllDates,d=t.days,c=t.disabledDates,u=t.startDay,h=t.weekendIndices,f=t.events,v=t.getRange?t.getRange():{},m=+v.start,y=+v.end,p=g(new Date(e).setDate(1)),w=p.getDay()-u,D=w<0?7:0;p.setMonth(p.getMonth()+1),p.setDate(0);var b=p.getDate(),q=[],S=D+7*((w+b)/7|0);S+=(w+b)%7?7:0;for(var M=1;M<=S;M++){var E=(M-1)%7,x=d[E],C=M-(w>=0?w:7+w),L=new Date(r,a,C),Y=f[+L],j=C<1||C>b,P=j?C<1?-1:1:0,k=j&&!l,O=k?"":L.getDate(),N=+L==+i,_=E===h[0]||E===h[1],I=m!==y,A="qs-square "+x;Y&&!k&&(A+=" qs-event"),j&&(A+=" qs-outside-current-month"),!l&&j||(A+=" qs-num"),N&&(A+=" qs-active"),(c[+L]||t.disabler(L)||_&&t.noWeekends||s&&+L<+s||o&&+L>+o)&&!k&&(A+=" qs-disabled"),+g(new Date)==+L&&(A+=" qs-current"),+L===m&&y&&I&&(A+=" qs-range-start"),+L>m&&+L<y&&(A+=" qs-range-middle"),+L===y&&m&&I&&(A+=" qs-range-end"),k&&(A+=" qs-empty",O=""),q.push('<div class="'+A+'" data-direction="'+P+'">'+O+"</div>")}var R=d.map((function(e){return'<div class="qs-square qs-day">'+e+"</div>"})).concat(q);return R.unshift('<div class="qs-squares'+(n?" qs-blur":"")+'">'),R.push("</div>"),R.join("")}function v(e,t){var n=e.overlayPlaceholder,a=e.overlayButton;return['<div class="qs-overlay'+(t?"":" qs-hidden")+'">',"<div>",'<input class="qs-overlay-year" placeholder="'+n+'" inputmode="numeric" />','<div class="qs-close">✕</div>',"</div>",'<div class="qs-overlay-month-container">'+e.overlayMonths.map((function(e,t){return'<div class="qs-overlay-month" data-month-num="'+t+'">'+e+"</div>"})).join("")+"</div>",'<div class="qs-submit qs-disabled">'+a+"</div>","</div>"].join("")}function m(e,t,n){var a=t.el,r=t.calendar.querySelector(".qs-active"),i=e.textContent,o=t.sibling;(a.disabled||a.readOnly)&&t.respectDisabledReadOnly||(t.dateSelected=n?void 0:new Date(t.currentYear,t.currentMonth,i),r&&r.classList.remove("qs-active"),n||e.classList.add("qs-active"),p(a,t,n),n||q(t),o&&(y({instance:t,deselect:n}),t.first&&!o.dateSelected&&(o.currentYear=t.currentYear,o.currentMonth=t.currentMonth,o.currentMonthName=t.currentMonthName),u(t),u(o)),t.onSelect(t,n?void 0:new Date(t.dateSelected)))}function y(e){var t=e.instance.first?e.instance:e.instance.sibling,n=t.sibling;t===e.instance?e.deselect?(t.minDate=t.originalMinDate,n.minDate=n.originalMinDate):n.minDate=t.dateSelected:e.deselect?(n.maxDate=n.originalMaxDate,t.maxDate=t.originalMaxDate):t.maxDate=n.dateSelected}function p(e,t,n){if(!t.nonInput)return n?e.value="":t.formatter!==s?t.formatter(e,t.dateSelected,t):void(e.value=t.dateSelected.toDateString())}function w(e,t,n,a){n||a?(n&&(t.currentYear=+n),a&&(t.currentMonth=+a)):(t.currentMonth+=e.contains("qs-right")?1:-1,12===t.currentMonth?(t.currentMonth=0,t.currentYear++):-1===t.currentMonth&&(t.currentMonth=11,t.currentYear--)),t.currentMonthName=t.months[t.currentMonth],u(t),t.onMonthChange(t)}function D(e){if(!e.noPosition){var t=e.position.top,n=e.position.right;if(e.position.centered)return e.calendarContainer.classList.add("qs-centered");var a=e.positionedEl.getBoundingClientRect(),r=e.el.getBoundingClientRect(),i=e.calendarContainer.getBoundingClientRect(),o=r.top-a.top+(t?-1*i.height:r.height)+"px",s=r.left-a.left+(n?r.width-i.width:0)+"px";e.calendarContainer.style.setProperty("top",o),e.calendarContainer.style.setProperty("left",s)}}function b(e){return"[object Date]"===x(e)&&"Invalid Date"!==e.toString()}function g(e){if(b(e)||"number"==typeof e&&!isNaN(e)){var t=new Date(+e);return new Date(t.getFullYear(),t.getMonth(),t.getDate())}}function q(e){e.disabled||!e.calendarContainer.classList.contains("qs-hidden")&&!e.alwaysShow&&("overlay"!==e.defaultView&&M(!0,e),e.calendarContainer.classList.add("qs-hidden"),e.onHide(e))}function S(e){e.disabled||(e.calendarContainer.classList.remove("qs-hidden"),"overlay"===e.defaultView&&M(!1,e),D(e),e.onShow(e))}function M(e,t){var n=t.calendar,a=n.querySelector(".qs-overlay"),r=a.querySelector(".qs-overlay-year"),i=n.querySelector(".qs-controls"),o=n.querySelector(".qs-squares");e?(a.classList.add("qs-hidden"),i.classList.remove("qs-blur"),o.classList.remove("qs-blur"),r.value=""):(a.classList.remove("qs-hidden"),i.classList.add("qs-blur"),o.classList.add("qs-blur"),r.focus())}function E(e,t,n,a){var r=isNaN(+(new Date).setFullYear(t.value||void 0)),i=r?null:t.value;if(13===e.which||13===e.keyCode||"click"===e.type)a?w(null,n,i,a):r||t.classList.contains("qs-disabled")||w(null,n,i);else if(n.calendar.contains(t)){n.calendar.querySelector(".qs-submit").classList[r?"add":"remove"]("qs-disabled")}}function x(e){return{}.toString.call(e)}function C(e){a.forEach((function(t){t!==e&&q(t)}))}function L(e){if(!e.__qs_shadow_dom){var t=e.which||e.keyCode,n=e.type,r=e.target,o=r.classList,s=a.filter((function(e){return e.calendar.contains(r)||e.el===r}))[0],l=s&&s.calendar.contains(r);if(!(s&&s.isMobile&&s.disableMobile))if("click"===n){if(!s)return a.forEach(q);if(s.disabled)return;var d=s.calendar,c=s.calendarContainer,h=s.disableYearOverlay,f=s.nonInput,v=d.querySelector(".qs-overlay-year"),y=!!d.querySelector(".qs-hidden"),p=d.querySelector(".qs-month-year").contains(r),D=r.dataset.monthNum;if(s.noPosition&&!l)(c.classList.contains("qs-hidden")?S:q)(s);else if(o.contains("qs-arrow"))w(o,s);else if(p||o.contains("qs-close"))h||M(!y,s);else if(D)E(e,v,s,D);else{if(o.contains("qs-disabled"))return;if(o.contains("qs-num")){var b=r.textContent,g=+r.dataset.direction,x=new Date(s.currentYear,s.currentMonth+g,b);if(g){s.currentYear=x.getFullYear(),s.currentMonth=x.getMonth(),s.currentMonthName=i[s.currentMonth],u(s);for(var L,Y=s.calendar.querySelectorAll('[data-direction="0"]'),j=0;!L;){var P=Y[j];P.textContent===b&&(L=P),j++}r=L}return void(+x==+s.dateSelected?m(r,s,!0):r.classList.contains("qs-disabled")||m(r,s))}o.contains("qs-submit")?E(e,v,s):f&&r===s.el&&(S(s),C(s))}}else if("focusin"===n&&s)S(s),C(s);else if("keydown"===n&&9===t&&s)q(s);else if("keydown"===n&&s&&!s.disabled){var k=!s.calendar.querySelector(".qs-overlay").classList.contains("qs-hidden");13===t&&k&&l?E(e,r,s):27===t&&k&&l&&M(!0,s)}else if("input"===n){if(!s||!s.calendar.contains(r))return;var O=s.calendar.querySelector(".qs-submit"),N=r.value.split("").reduce((function(e,t){return e||"0"!==t?e+(t.match(/[0-9]/)?t:""):""}),"").slice(0,4);r.value=N,O.classList[4===N.length?"remove":"add"]("qs-disabled")}}}function Y(e){L(e),e.__qs_shadow_dom=!0}function j(e,t){l.forEach((function(n){e.removeEventListener(n,t)}))}function P(){S(this)}function k(){q(this)}function O(e,t){var n=g(e),a=this.currentYear,r=this.currentMonth,i=this.sibling;if(null==e)return this.dateSelected=void 0,p(this.el,this,!0),i&&(y({instance:this,deselect:!0}),u(i)),u(this),this;if(!b(e))throw new Error("`setDate` needs a JavaScript Date object.");if(this.disabledDates[+n]||n<this.minDate||n>this.maxDate)throw new Error("You can't manually set a date that's disabled.");this.dateSelected=n,t&&(this.currentYear=n.getFullYear(),this.currentMonth=n.getMonth(),this.currentMonthName=this.months[n.getMonth()]),p(this.el,this),i&&(y({instance:this}),u(i));var o=a===n.getFullYear()&&r===n.getMonth();return o||t?u(this,n):o||u(this,new Date(a,r,1)),this}function N(e){return I(this,e,!0)}function _(e){return I(this,e)}function I(e,t,n){var a=e.dateSelected,r=e.first,i=e.sibling,o=e.minDate,s=e.maxDate,l=g(t),d=n?"Min":"Max";function c(){return"original"+d+"Date"}function h(){return d.toLowerCase()+"Date"}function f(){return"set"+d}function v(){throw new Error("Out-of-range date passed to "+f())}if(null==t)e[c()]=void 0,i?(i[c()]=void 0,n?(r&&!a||!r&&!i.dateSelected)&&(e.minDate=void 0,i.minDate=void 0):(r&&!i.dateSelected||!r&&!a)&&(e.maxDate=void 0,i.maxDate=void 0)):e[h()]=void 0;else{if(!b(t))throw new Error("Invalid date passed to "+f());i?((r&&n&&l>(a||s)||r&&!n&&l<(i.dateSelected||o)||!r&&n&&l>(i.dateSelected||s)||!r&&!n&&l<(a||o))&&v(),e[c()]=l,i[c()]=l,(n&&(r&&!a||!r&&!i.dateSelected)||!n&&(r&&!i.dateSelected||!r&&!a))&&(e[h()]=l,i[h()]=l)):((n&&l>(a||s)||!n&&l<(a||o))&&v(),e[h()]=l)}return i&&u(i),u(e),e}function A(){var e=this.first?this:this.sibling,t=e.sibling;return{start:e.dateSelected,end:t.dateSelected}}function R(){var e=this.shadowDom,t=this.positionedEl,n=this.calendarContainer,r=this.sibling,i=this;this.inlinePosition&&(a.some((function(e){return e!==i&&e.positionedEl===t}))||t.style.setProperty("position",null));n.remove(),a=a.filter((function(e){return e!==i})),r&&delete r.sibling,a.length||j(document,L);var o=a.some((function(t){return t.shadowDom===e}));for(var s in e&&!o&&j(e,Y),this)delete this[s];a.length||l.forEach((function(e){document.removeEventListener(e,L)}))}function F(e,t){var n=new Date(e);if(!b(n))throw new Error("Invalid date passed to `navigate`");this.currentYear=n.getFullYear(),this.currentMonth=n.getMonth(),u(this),t&&this.onMonthChange(this)}function B(){var e=!this.calendarContainer.classList.contains("qs-hidden"),t=!this.calendarContainer.querySelector(".qs-overlay").classList.contains("qs-hidden");e&&M(t,this)}t.default=function(e,t){var n=function(e,t){var n,l,d=function(e){var t=c(e);t.events&&(t.events=t.events.reduce((function(e,t){if(!b(t))throw new Error('"options.events" must only contain valid JavaScript Date objects.');return e[+g(t)]=!0,e}),{}));["startDate","dateSelected","minDate","maxDate"].forEach((function(e){var n=t[e];if(n&&!b(n))throw new Error('"options.'+e+'" needs to be a valid JavaScript Date object.');t[e]=g(n)}));var n=t.position,i=t.maxDate,l=t.minDate,d=t.dateSelected,u=t.overlayPlaceholder,h=t.overlayButton,f=t.startDay,v=t.id;if(t.startDate=g(t.startDate||d||new Date),t.disabledDates=(t.disabledDates||[]).reduce((function(e,t){var n=+g(t);if(!b(t))throw new Error('You supplied an invalid date to "options.disabledDates".');if(n===+g(d))throw new Error('"disabledDates" cannot contain the same date as "dateSelected".');return e[n]=1,e}),{}),t.hasOwnProperty("id")&&null==v)throw new Error("`id` cannot be `null` or `undefined`");if(null!=v){var m=a.filter((function(e){return e.id===v}));if(m.length>1)throw new Error("Only two datepickers can share an id.");m.length?(t.second=!0,t.sibling=m[0]):t.first=!0}var y=["tr","tl","br","bl","c"].some((function(e){return n===e}));if(n&&!y)throw new Error('"options.position" must be one of the following: tl, tr, bl, br, or c.');function p(e){throw new Error('"dateSelected" in options is '+(e?"less":"greater")+' than "'+(e||"max")+'Date".')}if(t.position=function(e){var t=e[0],n=e[1],a={};a[o[t]]=1,n&&(a[o[n]]=1);return a}(n||"bl"),i<l)throw new Error('"maxDate" in options is less than "minDate".');d&&(l>d&&p("min"),i<d&&p());if(["onSelect","onShow","onHide","onMonthChange","formatter","disabler"].forEach((function(e){"function"!=typeof t[e]&&(t[e]=s)})),["customDays","customMonths","customOverlayMonths"].forEach((function(e,n){var a=t[e],r=n?12:7;if(a){if(!Array.isArray(a)||a.length!==r||a.some((function(e){return"string"!=typeof e})))throw new Error('"'+e+'" must be an array with '+r+" strings.");t[n?n<2?"months":"overlayMonths":"days"]=a}})),f&&f>0&&f<7){var w=(t.customDays||r).slice(),D=w.splice(0,f);t.customDays=w.concat(D),t.startDay=+f,t.weekendIndices=[w.length-1,w.length]}else t.startDay=0,t.weekendIndices=[6,0];"string"!=typeof u&&delete t.overlayPlaceholder;"string"!=typeof h&&delete t.overlayButton;var q=t.defaultView;if(q&&"calendar"!==q&&"overlay"!==q)throw new Error('options.defaultView must either be "calendar" or "overlay".');return t.defaultView=q||"calendar",t}(t||{startDate:g(new Date),position:"bl",defaultView:"calendar"}),u=e;if("string"==typeof u)u="#"===u[0]?document.getElementById(u.slice(1)):document.querySelector(u);else{if("[object ShadowRoot]"===x(u))throw new Error("Using a shadow DOM as your selector is not supported.");for(var h,f=u.parentNode;!h;){var v=x(f);"[object HTMLDocument]"===v?h=!0:"[object ShadowRoot]"===v?(h=!0,n=f,l=f.host):f=f.parentNode}}if(!u)throw new Error("No selector / element found.");if(a.some((function(e){return e.el===u})))throw new Error("A datepicker already exists on that element.");var m=u===document.body,y=n?u.parentElement||n:m?document.body:u.parentElement,w=n?u.parentElement||l:y,D=document.createElement("div"),q=document.createElement("div");D.className="qs-datepicker-container qs-hidden",q.className="qs-datepicker";var M={shadowDom:n,customElement:l,positionedEl:w,el:u,parent:y,nonInput:"INPUT"!==u.nodeName,noPosition:m,position:!m&&d.position,startDate:d.startDate,dateSelected:d.dateSelected,disabledDates:d.disabledDates,minDate:d.minDate,maxDate:d.maxDate,noWeekends:!!d.noWeekends,weekendIndices:d.weekendIndices,calendarContainer:D,calendar:q,currentMonth:(d.startDate||d.dateSelected).getMonth(),currentMonthName:(d.months||i)[(d.startDate||d.dateSelected).getMonth()],currentYear:(d.startDate||d.dateSelected).getFullYear(),events:d.events||{},defaultView:d.defaultView,setDate:O,remove:R,setMin:N,setMax:_,show:P,hide:k,navigate:F,toggleOverlay:B,onSelect:d.onSelect,onShow:d.onShow,onHide:d.onHide,onMonthChange:d.onMonthChange,formatter:d.formatter,disabler:d.disabler,months:d.months||i,days:d.customDays||r,startDay:d.startDay,overlayMonths:d.overlayMonths||(d.months||i).map((function(e){return e.slice(0,3)})),overlayPlaceholder:d.overlayPlaceholder||"4-digit year",overlayButton:d.overlayButton||"Submit",disableYearOverlay:!!d.disableYearOverlay,disableMobile:!!d.disableMobile,isMobile:"ontouchstart"in window,alwaysShow:!!d.al
26323waysShow,id:d.id,showAllDates:!!d.showAllDates,respectDisabledReadOnly:!!d.respectDisabledReadOnly,first:d.first,second:d.second};if(d.sibling){var E=d.sibling,C=M,L=E.minDate||C.minDate,Y=E.maxDate||C.maxDate;C.sibling=E,E.sibling=C,E.minDate=L,E.maxDate=Y,C.minDate=L,C.maxDate=Y,E.originalMinDate=L,E.originalMaxDate=Y,C.originalMinDate=L,C.originalMaxDate=Y,E.getRange=A,C.getRange=A}d.dateSelected&&p(u,M);var j=getComputedStyle(w).position;m||j&&"static"!==j||(M.inlinePosition=!0,w.style.setProperty("position","relative"));var I=a.filter((function(e){return e.positionedEl===M.positionedEl}));I.some((function(e){return e.inlinePosition}))&&(M.inlinePosition=!0,I.forEach((function(e){e.inlinePosition=!0})));D.appendChild(q),y.appendChild(D),M.alwaysShow&&S(M);return M}(e,t);if(a.length||d(document),n.shadowDom&&(a.some((function(e){return e.shadowDom===n.shadowDom}))||d(n.shadowDom)),a.push(n),n.second){var l=n.sibling;y({instance:n,deselect:!n.dateSelected}),y({instance:l,deselect:!l.dateSelected}),u(l)}return u(n,n.startDate||n.dateSelected),n.alwaysShow&&D(n),n}}]).default})); 26324 26325/***/ }), 26326/* 4 */ 26327/***/ (function(module, exports, __webpack_require__) { 26328 26329var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Buttons for DataTables 1.7.1 26330 * ©2016-2021 SpryMedia Ltd - datatables.net/license 26331 */ 26332 26333(function( factory ){ 26334 if ( true ) { 26335 // AMD 26336 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) { 26337 return factory( $, window, document ); 26338 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 26339 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 26340 } 26341 else {} 26342}(function( $, window, document, undefined ) { 26343'use strict'; 26344var DataTable = $.fn.dataTable; 26345 26346 26347// Used for namespacing events added to the document by each instance, so they 26348// can be removed on destroy 26349var _instCounter = 0; 26350 26351// Button namespacing counter for namespacing events on individual buttons 26352var _buttonCounter = 0; 26353 26354var _dtButtons = DataTable.ext.buttons; 26355 26356// Allow for jQuery slim 26357function _fadeIn(el, duration, fn) { 26358 if ($.fn.animate) { 26359 el 26360 .stop() 26361 .fadeIn( duration, fn ); 26362 } 26363 else { 26364 el.css('display', 'block'); 26365 26366 if (fn) { 26367 fn.call(el); 26368 } 26369 } 26370} 26371 26372function _fadeOut(el, duration, fn) { 26373 if ($.fn.animate) { 26374 el 26375 .stop() 26376 .fadeOut( duration, fn ); 26377 } 26378 else { 26379 el.css('display', 'none'); 26380 26381 if (fn) { 26382 fn.call(el); 26383 } 26384 } 26385} 26386 26387/** 26388 * [Buttons description] 26389 * @param {[type]} 26390 * @param {[type]} 26391 */ 26392var Buttons = function( dt, config ) 26393{ 26394 // If not created with a `new` keyword then we return a wrapper function that 26395 // will take the settings object for a DT. This allows easy use of new instances 26396 // with the `layout` option - e.g. `topLeft: $.fn.dataTable.Buttons( ... )`. 26397 if ( !(this instanceof Buttons) ) { 26398 return function (settings) { 26399 return new Buttons( settings, dt ).container(); 26400 }; 26401 } 26402 26403 // If there is no config set it to an empty object 26404 if ( typeof( config ) === 'undefined' ) { 26405 config = {}; 26406 } 26407 26408 // Allow a boolean true for defaults 26409 if ( config === true ) { 26410 config = {}; 26411 } 26412 26413 // For easy configuration of buttons an array can be given 26414 if ( Array.isArray( config ) ) { 26415 config = { buttons: config }; 26416 } 26417 26418 this.c = $.extend( true, {}, Buttons.defaults, config ); 26419 26420 // Don't want a deep copy for the buttons 26421 if ( config.buttons ) { 26422 this.c.buttons = config.buttons; 26423 } 26424 26425 this.s = { 26426 dt: new DataTable.Api( dt ), 26427 buttons: [], 26428 listenKeys: '', 26429 namespace: 'dtb'+(_instCounter++) 26430 }; 26431 26432 this.dom = { 26433 container: $('<'+this.c.dom.container.tag+'/>') 26434 .addClass( this.c.dom.container.className ) 26435 }; 26436 26437 this._constructor(); 26438}; 26439 26440 26441$.extend( Buttons.prototype, { 26442 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 26443 * Public methods 26444 */ 26445 26446 /** 26447 * Get the action of a button 26448 * @param {int|string} Button index 26449 * @return {function} 26450 *//** 26451 * Set the action of a button 26452 * @param {node} node Button element 26453 * @param {function} action Function to set 26454 * @return {Buttons} Self for chaining 26455 */ 26456 action: function ( node, action ) 26457 { 26458 var button = this._nodeToButton( node ); 26459 26460 if ( action === undefined ) { 26461 return button.conf.action; 26462 } 26463 26464 button.conf.action = action; 26465 26466 return this; 26467 }, 26468 26469 /** 26470 * Add an active class to the button to make to look active or get current 26471 * active state. 26472 * @param {node} node Button element 26473 * @param {boolean} [flag] Enable / disable flag 26474 * @return {Buttons} Self for chaining or boolean for getter 26475 */ 26476 active: function ( node, flag ) { 26477 var button = this._nodeToButton( node ); 26478 var klass = this.c.dom.button.active; 26479 var jqNode = $(button.node); 26480 26481 if ( flag === undefined ) { 26482 return jqNode.hasClass( klass ); 26483 } 26484 26485 jqNode.toggleClass( klass, flag === undefined ? true : flag ); 26486 26487 return this; 26488 }, 26489 26490 /** 26491 * Add a new button 26492 * @param {object} config Button configuration object, base string name or function 26493 * @param {int|string} [idx] Button index for where to insert the button 26494 * @return {Buttons} Self for chaining 26495 */ 26496 add: function ( config, idx ) 26497 { 26498 var buttons = this.s.buttons; 26499 26500 if ( typeof idx === 'string' ) { 26501 var split = idx.split('-'); 26502 var base = this.s; 26503 26504 for ( var i=0, ien=split.length-1 ; i<ien ; i++ ) { 26505 base = base.buttons[ split[i]*1 ]; 26506 } 26507 26508 buttons = base.buttons; 26509 idx = split[ split.length-1 ]*1; 26510 } 26511 26512 this._expandButton( buttons, config, base !== undefined, idx ); 26513 this._draw(); 26514 26515 return this; 26516 }, 26517 26518 /** 26519 * Get the container node for the buttons 26520 * @return {jQuery} Buttons node 26521 */ 26522 container: function () 26523 { 26524 return this.dom.container; 26525 }, 26526 26527 /** 26528 * Disable a button 26529 * @param {node} node Button node 26530 * @return {Buttons} Self for chaining 26531 */ 26532 disable: function ( node ) { 26533 var button = this._nodeToButton( node ); 26534 26535 $(button.node) 26536 .addClass( this.c.dom.button.disabled ) 26537 .attr('disabled', true); 26538 26539 return this; 26540 }, 26541 26542 /** 26543 * Destroy the instance, cleaning up event handlers and removing DOM 26544 * elements 26545 * @return {Buttons} Self for chaining 26546 */ 26547 destroy: function () 26548 { 26549 // Key event listener 26550 $('body').off( 'keyup.'+this.s.namespace ); 26551 26552 // Individual button destroy (so they can remove their own events if 26553 // needed). Take a copy as the array is modified by `remove` 26554 var buttons = this.s.buttons.slice(); 26555 var i, ien; 26556 26557 for ( i=0, ien=buttons.length ; i<ien ; i++ ) { 26558 this.remove( buttons[i].node ); 26559 } 26560 26561 // Container 26562 this.dom.container.remove(); 26563
26564 // Remove from the settings object collection 26565 var buttonInsts = this.s.dt.settings()[0]; 26566 26567 for ( i=0, ien=buttonInsts.length ; i<ien ; i++ ) { 26568 if ( buttonInsts.inst === this ) { 26569 buttonInsts.splice( i, 1 ); 26570 break; 26571 } 26572 } 26573 26574 return this; 26575 }, 26576 26577 /** 26578 * Enable / disable a button 26579 * @param {node} node Button node 26580 * @param {boolean} [flag=true] Enable / disable flag 26581 * @return {Buttons} Self for chaining 26582 */ 26583 enable: function ( node, flag ) 26584 { 26585 if ( flag === false ) { 26586 return this.disable( node ); 26587 } 26588 26589 var button = this._nodeToButton( node ); 26590 $(button.node) 26591 .removeClass( this.c.dom.button.disabled ) 26592 .removeAttr('disabled'); 26593 26594 return this; 26595 }, 26596 26597 /** 26598 * Get the instance name for the button set selector 26599 * @return {string} Instance name 26600 */ 26601 name: function () 26602 { 26603 return this.c.name; 26604 }, 26605 26606 /** 26607 * Get a button's node of the buttons container if no button is given 26608 * @param {node} [node] Button node 26609 * @return {jQuery} Button element, or container 26610 */ 26611 node: function ( node ) 26612 { 26613 if ( ! node ) { 26614 return this.dom.container; 26615 } 26616 26617 var button = this._nodeToButton( node ); 26618 return $(button.node); 26619 }, 26620 26621 /** 26622 * Set / get a processing class on the selected button 26623 * @param {element} node Triggering button node 26624 * @param {boolean} flag true to add, false to remove, undefined to get 26625 * @return {boolean|Buttons} Getter value or this if a setter. 26626 */ 26627 processing: function ( node, flag ) 26628 { 26629 var dt = this.s.dt; 26630 var button = this._nodeToButton( node ); 26631 26632 if ( flag === undefined ) { 26633 return $(button.node).hasClass( 'processing' ); 26634 } 26635 26636 $(button.node).toggleClass( 'processing', flag ); 26637 26638 $(dt.table().node()).triggerHandler( 'buttons-processing.dt', [ 26639 flag, dt.button( node ), dt, $(node), button.conf 26640 ] ); 26641 26642 return this; 26643 }, 26644 26645 /** 26646 * Remove a button. 26647 * @param {node} node Button node 26648 * @return {Buttons} Self for chaining 26649 */ 26650 remove: function ( node ) 26651 { 26652 var button = this._nodeToButton( node ); 26653 var host = this._nodeToHost( node ); 26654 var dt = this.s.dt; 26655 26656 // Remove any child buttons first 26657 if ( button.buttons.length ) { 26658 for ( var i=button.buttons.length-1 ; i>=0 ; i-- ) { 26659 this.remove( button.buttons[i].node ); 26660 } 26661 } 26662 26663 // Allow the button to remove event handlers, etc 26664 if ( button.conf.destroy ) { 26665 button.conf.destroy.call( dt.button(node), dt, $(node), button.conf ); 26666 } 26667 26668 this._removeKey( button.conf ); 26669 26670 $(button.node).remove(); 26671 26672 var idx = $.inArray( button, host ); 26673 host.splice( idx, 1 ); 26674 26675 return this; 26676 }, 26677 26678 /** 26679 * Get the text for a button 26680 * @param {int|string} node Button index 26681 * @return {string} Button text 26682 *//** 26683 * Set the text for a button 26684 * @param {int|string|function} node Button index 26685 * @param {string} label Text 26686 * @return {Buttons} Self for chaining 26687 */ 26688 text: function ( node, label ) 26689 { 26690 var button = this._nodeToButton( node ); 26691 var buttonLiner = this.c.dom.collection.buttonLiner; 26692 var linerTag = button.inCollection && buttonLiner && buttonLiner.tag ? 26693 buttonLiner.tag : 26694 this.c.dom.buttonLiner.tag; 26695 var dt = this.s.dt; 26696 var jqNode = $(button.node); 26697 var text = function ( opt ) { 26698 return typeof opt === 'function' ? 26699 opt( dt, jqNode, button.conf ) : 26700 opt; 26701 }; 26702 26703 if ( label === undefined ) { 26704 return text( button.conf.text ); 26705 } 26706 26707 button.conf.text = label; 26708 26709 if ( linerTag ) { 26710 jqNode.children( linerTag ).html( text(label) ); 26711 } 26712 else { 26713 jqNode.html( text(label) ); 26714 } 26715 26716 return this; 26717 }, 26718 26719 26720 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 26721 * Constructor 26722 */ 26723 26724 /** 26725 * Buttons constructor 26726 * @private 26727 */ 26728 _constructor: function () 26729 { 26730 var that = this; 26731 var dt = this.s.dt; 26732 var dtSettings = dt.settings()[0]; 26733 var buttons = this.c.buttons; 26734 26735 if ( ! dtSettings._buttons ) { 26736 dtSettings._buttons = []; 26737 } 26738 26739 dtSettings._buttons.push( { 26740 inst: this, 26741 name: this.c.name 26742 } ); 26743 26744 for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { 26745 this.add( buttons[i] ); 26746 } 26747 26748 dt.on( 'destroy', function ( e, settings ) { 26749 if ( settings === dtSettings ) { 26750 that.destroy(); 26751 } 26752 } ); 26753 26754 // Global key event binding to listen for button keys 26755 $('body').on( 'keyup.'+this.s.namespace, function ( e ) { 26756 if ( ! document.activeElement || document.activeElement === document.body ) { 26757 // SUse a string of characters for fast lookup of if we need to 26758 // handle this 26759 var character = String.fromCharCode(e.keyCode).toLowerCase(); 26760 26761 if ( that.s.listenKeys.toLowerCase().indexOf( character ) !== -1 ) { 26762 that._keypress( character, e ); 26763 } 26764 } 26765 } ); 26766 }, 26767 26768 26769 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 26770 * Private methods 26771 */ 26772 26773 /** 26774 * Add a new button to the key press listener 26775 * @param {object} conf Resolved button configuration object 26776 * @private 26777 */ 26778 _addKey: function ( conf ) 26779 { 26780 if ( conf.key ) { 26781 this.s.listenKeys += $.isPlainObject( conf.key ) ? 26782 conf.key.key : 26783 conf.key; 26784 } 26785 }, 26786 26787 /**
26788 * Insert the buttons into the container. Call without parameters! 26789 * @param {node} [container] Recursive only - Insert point 26790 * @param {array} [buttons] Recursive only - Buttons array 26791 * @private 26792 */ 26793 _draw: function ( container, buttons ) 26794 { 26795 if ( ! container ) { 26796 container = this.dom.container; 26797 buttons = this.s.buttons; 26798 } 26799 26800 container.children().detach(); 26801 26802 for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { 26803 container.append( buttons[i].inserter ); 26804 container.append( ' ' ); 26805 26806 if ( buttons[i].buttons && buttons[i].buttons.length ) { 26807 this._draw( buttons[i].collection, buttons[i].buttons ); 26808 } 26809 } 26810 }, 26811 26812 /** 26813 * Create buttons from an array of buttons 26814 * @param {array} attachTo Buttons array to attach to 26815 * @param {object} button Button definition 26816 * @param {boolean} inCollection true if the button is in a collection 26817 * @private 26818 */ 26819 _expandButton: function ( attachTo, button, inCollection, attachPoint ) 26820 { 26821 var dt = this.s.dt; 26822 var buttonCounter = 0; 26823 var buttons = ! Array.isArray( button ) ? 26824 [ button ] : 26825 button; 26826 26827 for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { 26828 var conf = this._resolveExtends( buttons[i] ); 26829 26830 if ( ! conf ) { 26831 continue; 26832 } 26833 26834 // If the configuration is an array, then expand the buttons at this 26835 // point 26836 if ( Array.isArray( conf ) ) { 26837 this._expandButton( attachTo, conf, inCollection, attachPoint ); 26838 continue; 26839 } 26840 26841 var built = this._buildButton( conf, inCollection ); 26842 if ( ! built ) { 26843 continue; 26844 } 26845 26846 if ( attachPoint !== undefined && attachPoint !== null ) { 26847 attachTo.splice( attachPoint, 0, built ); 26848 attachPoint++; 26849 } 26850 else { 26851 attachTo.push( built ); 26852 } 26853 26854 if ( built.conf.buttons ) { 26855 built.collection = $('<'+this.c.dom.collection.tag+'/>'); 26856 26857 built.conf._collection = built.collection; 26858 26859 this._expandButton( built.buttons, built.conf.buttons, true, attachPoint ); 26860 } 26861 26862 // init call is made here, rather than buildButton as it needs to 26863 // be selectable, and for that it needs to be in the buttons array 26864 if ( conf.init ) { 26865 conf.init.call( dt.button( built.node ), dt, $(built.node), conf ); 26866 } 26867 26868 buttonCounter++; 26869 } 26870 }, 26871 26872 /** 26873 * Create an individual button 26874 * @param {object} config Resolved button configuration 26875 * @param {boolean} inCollection `true` if a collection button 26876 * @return {jQuery} Created button node (jQuery) 26877 * @private 26878 */ 26879 _buildButton: function ( config, inCollection ) 26880 { 26881 var buttonDom = this.c.dom.button; 26882 var linerDom = this.c.dom.buttonLiner; 26883 var collectionDom = this.c.dom.collection; 26884 var dt = this.s.dt; 26885 var text = function ( opt ) { 26886 return typeof opt === 'function' ? 26887 opt( dt, button, config ) : 26888 opt; 26889 }; 26890 26891 if ( inCollection && collectionDom.button ) { 26892 buttonDom = collectionDom.button; 26893 } 26894 26895 if ( inCollection && collectionDom.buttonLiner ) { 26896 linerDom = collectionDom.buttonLiner; 26897 } 26898 26899 // Make sure that the button is available based on whatever requirements 26900 // it has. For example, PDF button require pdfmake 26901 if ( config.available && ! config.available( dt, config ) ) { 26902 return false; 26903 } 26904 26905 var action = function ( e, dt, button, config ) { 26906 config.action.call( dt.button( button ), e, dt, button, config ); 26907 26908 $(dt.table().node()).triggerHandler( 'buttons-action.dt', [ 26909 dt.button( button ), dt, button, config 26910 ] ); 26911 }; 26912 26913 var tag = config.tag || buttonDom.tag; 26914 var clickBlurs = config.clickBlurs === undefined ? true : config.clickBlurs 26915 var button = $('<'+tag+'/>') 26916 .addClass( buttonDom.className ) 26917 .attr( 'tabindex', this.s.dt.settings()[0].iTabIndex ) 26918 .attr( 'aria-controls', this.s.dt.table().node().id ) 26919 .on( 'click.dtb', function (e) { 26920 e.preventDefault(); 26921 26922 if ( ! button.hasClass( buttonDom.disabled ) && config.action ) { 26923 action( e, dt, button, config ); 26924 } 26925 if( clickBlurs ) { 26926 button.trigger('blur'); 26927 } 26928 } ) 26929 .on( 'keyup.dtb', function (e) { 26930 if ( e.keyCode === 13 ) { 26931 if ( ! button.hasClass( buttonDom.disabled ) && config.action ) { 26932 action( e, dt, button, config ); 26933 } 26934 } 26935 } ); 26936 26937 // Make `a` tags act like a link 26938 if ( tag.toLowerCase() === 'a' ) { 26939 button.attr( 'href', '#' ); 26940 } 26941 26942 // Button tags should have `type=button` so they don't have any default behaviour 26943 if ( tag.toLowerCase() === 'button' ) { 26944 button.attr( 'type', 'button' ); 26945 } 26946 26947 if ( linerDom.tag ) { 26948 var liner = $('<'+linerDom.tag+'/>') 26949 .html( text( config.text ) ) 26950 .addClass( linerDom.className ); 26951 26952 if ( linerDom.tag.toLowerCase() === 'a' ) { 26953 liner.attr( 'href', '#' ); 26954 } 26955 26956 button.append( liner ); 26957 } 26958 else { 26959 button.html( text( config.text ) ); 26960 } 26961 26962 if ( config.enabled === false ) { 26963 button.addClass( buttonDom.disabled ); 26964 } 26965 26966 if ( config.className ) { 26967 button.addClass( config.className ); 26968 } 26969 26970 if ( config.titleAttr ) { 26971 button.attr( 'title', text( config.titleAttr ) ); 26972 } 26973 26974 if ( config.attr ) { 26975 button.attr( config.attr ); 26976 } 26977 26978 if ( ! config.namespace ) { 26979 config.namespace = '.dt-button-'+(_buttonCounter++); 26980 } 26981 26982 var buttonContainer = this.c.dom.buttonContainer; 26983 var inserter; 26984 if ( buttonContainer && buttonContainer.tag ) { 26985 inserter = $('<'+buttonContainer.tag+'/>') 26986 .addClass( buttonContainer.className ) 26987 .append( button ); 26988 } 26989 else { 26990 inserter = button; 26991 } 26992 26993 this._addKey( config ); 26994 26995 // Style integration callback for DOM manipulation 26996 // Note that this is _not_ documented. It is currently 26997 // for style integration only 26998 if( this.c.buttonCreated ) { 26999 inserter = this.c.buttonCreated( config, inserter ); 27000 } 27001 27002 return { 27003 conf: config, 27004 node: button.get(0), 27005 inserter: inserter, 27006 buttons: [], 27007 inCollection: inCollection, 27008 collection: null 27009 }; 27010 }, 27011 27012 /** 27013 * Get the button object from a node (recursive) 27014 * @param {node} node Button node 27015 * @param {array} [buttons] Button array, uses base if not defined 27016 * @return {object} Button object 27017 * @private 27018 */ 27019 _nodeToButton: function ( node, buttons ) 27020 { 27021 if ( ! buttons ) { 27022 buttons = this.s.buttons; 27023 } 27024 27025 for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { 27026 if ( buttons[i].node === node ) { 27027 return buttons[i]; 27028 } 27029 27030 if ( buttons[i].buttons.length ) { 27031 var ret = this._nodeToButton( node, buttons[i].buttons ); 27032 27033 if ( ret ) { 27034 return ret; 27035 } 27036 } 27037 } 27038 }, 27039 27040 /** 27041 * Get container array for a button from a button node (recursive) 27042 * @param {node} node Button node 27043 * @param {array} [buttons] Button array, uses base if not defined 27044 * @return {array} Button's host array 27045 * @private 27046 */ 27047 _nodeToHost: function ( node, buttons ) 27048 { 27049 if ( ! buttons ) { 27050 buttons = this.s.buttons; 27051 } 27052 27053 for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { 27054 if ( buttons[i].node === node ) { 27055 return buttons; 27056 } 27057 27058 if ( buttons[i].buttons.length ) { 27059 var ret = this._nodeToHost( node, buttons[i].buttons ); 27060 27061 if ( ret ) { 27062 return ret; 27063 } 27064 } 27065 } 27066 }, 27067 27068 /** 27069 * Handle a key press - determine if any button's key configured matches 27070 * what was typed and trigger the action if so. 27071 * @param {string} character The character pressed 27072 * @param {object} e Key event that triggered this call 27073 * @private 27074 */ 27075 _keypress: function ( character, e ) 27076 { 27077 // Check if this button press already activated on another instance of Buttons 27078 if ( e._buttonsHandled ) { 27079 return; 27080 } 27081 27082 var run = function ( conf, node ) { 27083 if ( ! conf.key ) { 27084 return; 27085 } 27086 27087 if ( conf.key === character ) { 27088 e._buttonsHandled = true; 27089 $(node).click(); 27090 } 27091 else if ( $.isPlainObject( conf.key ) ) { 27092 if ( conf.key.key !== character ) { 27093 return; 27094 } 27095
27096 if ( conf.key.shiftKey && ! e.shiftKey ) { 27097 return; 27098 } 27099 27100 if ( conf.key.altKey && ! e.altKey ) { 27101 return; 27102 } 27103 27104 if ( conf.key.ctrlKey && ! e.ctrlKey ) { 27105 return; 27106 } 27107 27108 if ( conf.key.metaKey && ! e.metaKey ) { 27109 return; 27110 } 27111 27112 // Made it this far - it is good 27113 e._buttonsHandled = true; 27114 $(node).click(); 27115 } 27116 }; 27117 27118 var recurse = function ( a ) { 27119 for ( var i=0, ien=a.length ; i<ien ; i++ ) { 27120 run( a[i].conf, a[i].node ); 27121 27122 if ( a[i].buttons.length ) { 27123 recurse( a[i].buttons ); 27124 } 27125 } 27126 }; 27127 27128 recurse( this.s.buttons ); 27129 }, 27130 27131 /** 27132 * Remove a key from the key listener for this instance (to be used when a 27133 * button is removed) 27134 * @param {object} conf Button configuration 27135 * @private 27136 */ 27137 _removeKey: function ( conf ) 27138 { 27139 if ( conf.key ) { 27140 var character = $.isPlainObject( conf.key ) ? 27141 conf.key.key : 27142 conf.key; 27143 27144 // Remove only one character, as multiple buttons could have the 27145 // same listening key 27146 var a = this.s.listenKeys.split(''); 27147 var idx = $.inArray( character, a ); 27148 a.splice( idx, 1 ); 27149 this.s.listenKeys = a.join(''); 27150 } 27151 }, 27152 27153 /** 27154 * Resolve a button configuration 27155 * @param {string|function|object} conf Button config to resolve 27156 * @return {object} Button configuration 27157 * @private 27158 */ 27159 _resolveExtends: function ( conf ) 27160 { 27161 var dt = this.s.dt; 27162 var i, ien; 27163 var toConfObject = function ( base ) { 27164 var loop = 0; 27165 27166 // Loop until we have resolved to a button configuration, or an 27167 // array of button configurations (which will be iterated 27168 // separately) 27169 while ( ! $.isPlainObject(base) && ! Array.isArray(base) ) { 27170 if ( base === undefined ) { 27171 return; 27172 } 27173 27174 if ( typeof base === 'function' ) { 27175 base = base( dt, conf ); 27176 27177 if ( ! base ) { 27178 return false; 27179 } 27180 } 27181 else if ( typeof base === 'string' ) { 27182 if ( ! _dtButtons[ base ] ) { 27183 throw 'Unknown button type: '+base; 27184 } 27185 27186 base = _dtButtons[ base ]; 27187 } 27188 27189 loop++; 27190 if ( loop > 30 ) { 27191 // Protect against misconfiguration killing the browser 27192 throw 'Buttons: Too many iterations'; 27193 } 27194 } 27195 27196 return Array.isArray( base ) ? 27197 base : 27198 $.extend( {}, base ); 27199 }; 27200 27201 conf = toConfObject( conf ); 27202 27203 while ( conf && conf.extend ) { 27204 // Use `toConfObject` in case the button definition being extended 27205 // is itself a string or a function 27206 if ( ! _dtButtons[ conf.extend ] ) { 27207 throw 'Cannot extend unknown button type: '+conf.extend; 27208 } 27209 27210 var objArray = toConfObject( _dtButtons[ conf.extend ] ); 27211 if ( Array.isArray( objArray ) ) { 27212 return objArray; 27213 } 27214 else if ( ! objArray ) { 27215 // This is a little brutal as it might be possible to have a 27216 // valid button without the extend, but if there is no extend 27217 // then the host button would be acting in an undefined state 27218 return false; 27219 } 27220 27221 // Stash the current class name 27222 var originalClassName = objArray.className; 27223 27224 conf = $.extend( {}, objArray, conf ); 27225 27226 // The extend will have overwritten the original class name if the 27227 // `conf` object also assigned a class, but we want to concatenate 27228 // them so they are list that is combined from all extended buttons 27229 if ( originalClassName && conf.className !== originalClassName ) { 27230 conf.className = originalClassName+' '+conf.className; 27231 } 27232 27233 // Buttons to be added to a collection -gives the ability to define 27234 // if buttons should be added to the start or end of a collection 27235 var postfixButtons = conf.postfixButtons; 27236 if ( postfixButtons ) { 27237 if ( ! conf.buttons ) { 27238 conf.buttons = []; 27239 } 27240 27241 for ( i=0, ien=postfixButtons.length ; i<ien ; i++ ) { 27242 conf.buttons.push( postfixButtons[i] ); 27243 } 27244 27245 conf.postfixButtons = null; 27246 } 27247 27248 var prefixButtons = conf.prefixButtons; 27249 if ( prefixButtons ) { 27250 if ( ! conf.buttons ) { 27251 conf.buttons = []; 27252 } 27253 27254 for ( i=0, ien=prefixButtons.length ; i<ien ; i++ ) { 27255 conf.buttons.splice( i, 0, prefixButtons[i] ); 27256 } 27257 27258 conf.prefixButtons = null; 27259 } 27260 27261 // Although we want the `conf` object to overwrite almost all of 27262 // the properties of the object being extended, the `extend` 27263 // property should come from the object being extended 27264 conf.extend = objArray.extend; 27265 } 27266 27267 return conf; 27268 }, 27269 27270 /** 27271 * Display (and replace if there is an existing one) a popover attached to a button 27272 * @param {string|node} content Content to show 27273 * @param {DataTable.Api} hostButton DT API instance of the button 27274 * @param {object} inOpts Options (see object below for all options) 27275 */ 27276 _popover: function ( content, hostButton, inOpts ) { 27277 var dt = hostButton; 27278 var buttonsSettings = this.c; 27279 var options = $.extend( { 27280 align: 'button-left', // button-right, dt-container 27281 autoClose: false, 27282 background: true, 27283 backgroundClassName: 'dt-button-background', 27284 contentClassName: buttonsSettings.dom.collection.className, 27285 collectionLayout: '', 27286 collectionTitle: '', 27287 dropup: false, 27288 fade: 400, 27289 rightAlignClassName: 'dt-button-right', 27290 tag: buttonsSettings.dom.collection.tag 27291 }, inOpts ); 27292 var hostNode = hostButton.node(); 27293 27294 var close = function () { 27295 _fadeOut( 27296 $('.dt-button-collection'), 27297 options.fade, 27298 function () { 27299 $(this).detach(); 27300 } 27301 ); 27302 27303 $(dt.buttons( '[aria-haspopup="true"][aria-expanded="true"]' ).nodes()) 27304 .attr('aria-expanded', 'false'); 27305 27306 $('div.dt-button-background').off( 'click.dtb-collection' );
27307 Buttons.background( false, options.backgroundClassName, options.fade, hostNode ); 27308 27309 $('body').off( '.dtb-collection' ); 27310 dt.off( 'buttons-action.b-internal' ); 27311 }; 27312 27313 if (content === false) { 27314 close(); 27315 } 27316 27317 var existingExpanded = $(dt.buttons( '[aria-haspopup="true"][aria-expanded="true"]' ).nodes()); 27318 if ( existingExpanded.length ) { 27319 hostNode = existingExpanded.eq(0); 27320 27321 close(); 27322 } 27323 27324 var display = $('<div/>') 27325 .addClass('dt-button-collection') 27326 .addClass(options.collectionLayout) 27327 .css('display', 'none'); 27328 27329 content = $(content) 27330 .addClass(options.contentClassName) 27331 .attr('role', 'menu') 27332 .appendTo(display); 27333 27334 hostNode.attr( 'aria-expanded', 'true' ); 27335 27336 if ( hostNode.parents('body')[0] !== document.body ) { 27337 hostNode = document.body.lastChild; 27338 } 27339 27340 if ( options.collectionTitle ) { 27341 display.prepend('<div class="dt-button-collection-title">'+options.collectionTitle+'</div>'); 27342 } 27343 27344 _fadeIn( display.insertAfter( hostNode ), options.fade ); 27345 27346 var tableContainer = $( hostButton.table().container() ); 27347 var position = display.css( 'position' ); 27348 27349 if ( options.align === 'dt-container' ) { 27350 hostNode = hostNode.parent(); 27351 display.css('width', tableContainer.width()); 27352 } 27353 27354 // Align the popover relative to the DataTables container 27355 // Useful for wide popovers such as SearchPanes 27356 if (position === 'absolute') { 27357 // Align relative to the host button 27358 var hostPosition = hostNode.position(); 27359 var buttonPosition = $(hostButton.node()).position(); 27360 27361 display.css( { 27362 top: buttonPosition.top + hostNode.outerHeight(), 27363 left: hostPosition.left 27364 } ); 27365 27366 // calculate overflow when positioned beneath 27367 var collectionHeight = display.outerHeight(); 27368 var tableBottom = tableContainer.offset().top + tableContainer.height(); 27369 var listBottom = buttonPosition.top + hostNode.outerHeight() + collectionHeight; 27370 var bottomOverflow = listBottom - tableBottom; 27371 27372 // calculate overflow when positioned above 27373 var listTop = buttonPosition.top - collectionHeight; 27374 var tableTop = tableContainer.offset().top; 27375 var topOverflow = tableTop - listTop; 27376 27377 // if bottom overflow is larger, move to the top because it fits better, or if dropup is requested 27378 var moveTop = buttonPosition.top - collectionHeight - 5; 27379 if ( (bottomOverflow > topOverflow || options.dropup) && -moveTop < tableTop ) { 27380 display.css( 'top', moveTop); 27381 } 27382 27383 // Get the size of the container (left and width - and thus also right) 27384 var tableLeft = tableContainer.offset().left; 27385 var tableWidth = tableContainer.width(); 27386 var tableRight = tableLeft + tableWidth; 27387 27388 // Get the size of the popover (left and width - and ...) 27389 var popoverLeft = display.offset().left; 27390 var popoverWidth = display.width(); 27391 var popoverRight = popoverLeft + popoverWidth; 27392 27393 // Get the size of the host buttons (left and width - and ...) 27394 var buttonsLeft = hostNode.offset().left; 27395 var buttonsWidth = hostNode.outerWidth() 27396 var buttonsRight = buttonsLeft + buttonsWidth; 27397 27398 if ( 27399 display.hasClass( options.rightAlignClassName ) || 27400 display.hasClass( options.leftAlignClassName ) || 27401 options.align === 'dt-container' 27402 ){ 27403 // You've then got all the numbers you need to do some calculations and if statements, 27404 // so we can do some quick JS maths and apply it only once 27405 // If it has the right align class OR the buttons are right aligned OR the button container is floated right, 27406 // then calculate left position for the popover to align the popover to the right hand 27407 // side of the button - check to see if the left of the popover is inside the table container. 27408 // If not, move the popover so it is, but not more than it means that the popover is to the right of the table container 27409 var popoverShuffle = 0; 27410 if ( display.hasClass( options.rightAlignClassName )) { 27411 popoverShuffle = buttonsRight - popoverRight; 27412 if(tableLeft > (popoverLeft + popoverShuffle)){ 27413 var leftGap = tableLeft - (popoverLeft + popoverShuffle); 27414 var rightGap = tableRight - (popoverRight + popoverShuffle); 27415 27416 if(leftGap > rightGap){ 27417 popoverShuffle += rightGap; 27418 } 27419 else { 27420 popoverShuffle += leftGap; 27421 } 27422 } 27423 } 27424 // else attempt to left align the popover to the button. Similar to above, if the popover's right goes past the table container's right, 27425 // then move it back, but not so much that it goes past the left of the table container 27426 else { 27427 popoverShuffle = tableLeft - popoverLeft; 27428 27429 if(tableRight < (popoverRight + popoverShuffle)){ 27430 var leftGap = tableLeft - (popoverLeft + popoverShuffle); 27431 var rightGap = tableRight - (popoverRight + popoverShuffle); 27432 27433 if(leftGap > rightGap ){ 27434 popoverShuffle += rightGap; 27435 } 27436 else { 27437 popoverShuffle += leftGap; 27438 } 27439 27440 } 27441 } 27442 27443 display.css('left', display.position().left + popoverShuffle); 27444 } 27445 else { 27446 var top = hostNode.offset().top 27447 var popoverShuffle = 0; 27448 27449 popoverShuffle = options.align === 'button-right' 27450 ? buttonsRight - popoverRight 27451 : buttonsLeft - popoverLeft; 27452 27453 display.css('left', display.position().left + popoverShuffle); 27454 } 27455 27456 27457 } 27458 else { 27459 // Fix position - centre on screen 27460 var top = display.height() / 2; 27461 if ( top > $(window).height() / 2 ) { 27462 top = $(window).height() / 2; 27463 } 27464 27465 display.css( 'marginTop', top*-1 ); 27466 } 27467 27468 if ( options.background ) { 27469 Buttons.background( true, options.backgroundClassName, options.fade, hostNode ); 27470 } 27471 27472 // This is bonkers, but if we don't have a click listener on the 27473 // background element, iOS Safari will ignore the body click 27474 // listener below. An empty function here is all that is 27475 // required to make it work... 27476 $('div.dt-button-background').on( 'click.dtb-collection', function () {} ); 27477 27478 $('body') 27479 .on( 'click.dtb-collection', function (e) {
27480 // andSelf is deprecated in jQ1.8, but we want 1.7 compat 27481 var back = $.fn.addBack ? 'addBack' : 'andSelf'; 27482 var parent = $(e.target).parent()[0]; 27483 27484 if (( ! $(e.target).parents()[back]().filter( content ).length && !$(parent).hasClass('dt-buttons')) || $(e.target).hasClass('dt-button-background')) { 27485 close(); 27486 } 27487 } ) 27488 .on( 'keyup.dtb-collection', function (e) { 27489 if ( e.keyCode === 27 ) { 27490 close(); 27491 } 27492 } ); 27493 27494 if ( options.autoClose ) { 27495 setTimeout( function () { 27496 dt.on( 'buttons-action.b-internal', function (e, btn, dt, node) { 27497 if ( node[0] === hostNode[0] ) { 27498 return; 27499 } 27500 close(); 27501 } ); 27502 }, 0); 27503 } 27504 27505 $(display).trigger('buttons-popover.dt'); 27506 } 27507} ); 27508 27509 27510 27511/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 27512 * Statics 27513 */ 27514 27515/** 27516 * Show / hide a background layer behind a collection 27517 * @param {boolean} Flag to indicate if the background should be shown or 27518 * hidden 27519 * @param {string} Class to assign to the background 27520 * @static 27521 */ 27522Buttons.background = function ( show, className, fade, insertPoint ) { 27523 if ( fade === undefined ) { 27524 fade = 400; 27525 } 27526 if ( ! insertPoint ) { 27527 insertPoint = document.body; 27528 } 27529 27530 if ( show ) { 27531 _fadeIn( 27532 $('<div/>') 27533 .addClass( className ) 27534 .css( 'display', 'none' ) 27535 .insertAfter( insertPoint ), 27536 fade 27537 ); 27538 } 27539 else { 27540 _fadeOut( 27541 $('div.'+className), 27542 fade, 27543 function () { 27544 $(this) 27545 .removeClass( className ) 27546 .remove(); 27547 } 27548 ); 27549 } 27550}; 27551 27552/** 27553 * Instance selector - select Buttons instances based on an instance selector 27554 * value from the buttons assigned to a DataTable. This is only useful if 27555 * multiple instances are attached to a DataTable. 27556 * @param {string|int|array} Instance selector - see `instance-selector` 27557 * documentation on the DataTables site 27558 * @param {array} Button instance array that was attached to the DataTables 27559 * settings object 27560 * @return {array} Buttons instances 27561 * @static 27562 */ 27563Buttons.instanceSelector = function ( group, buttons ) 27564{ 27565 if ( group === undefined || group === null ) { 27566 return $.map( buttons, function ( v ) { 27567 return v.inst; 27568 } ); 27569 } 27570 27571 var ret = []; 27572 var names = $.map( buttons, function ( v ) { 27573 return v.name; 27574 } ); 27575 27576 // Flatten the group selector into an array of single options 27577 var process = function ( input ) { 27578 if ( Array.isArray( input ) ) { 27579 for ( var i=0, ien=input.length ; i<ien ; i++ ) { 27580 process( input[i] ); 27581 } 27582 return; 27583 } 27584 27585 if ( typeof input === 'string' ) { 27586 if ( input.indexOf( ',' ) !== -1 ) { 27587 // String selector, list of names 27588 process( input.split(',') ); 27589 } 27590 else { 27591 // String selector individual name 27592 var idx = $.inArray( input.trim(), names ); 27593 27594 if ( idx !== -1 ) { 27595 ret.push( buttons[ idx ].inst ); 27596 } 27597 } 27598 } 27599 else if ( typeof input === 'number' ) { 27600 // Index selector 27601 ret.push( buttons[ input ].inst ); 27602 } 27603 }; 27604 27605 process( group ); 27606 27607 return ret; 27608}; 27609 27610/** 27611 * Button selector - select one or more buttons from a selector input so some 27612 * operation can be performed on them. 27613 * @param {array} Button instances array that the selector should operate on 27614 * @param {string|int|node|jQuery|array} Button selector - see 27615 * `button-selector` documentation on the DataTables site 27616 * @return {array} Array of objects containing `inst` and `idx` properties of 27617 * the selected buttons so you know which instance each button belongs to. 27618 * @static 27619 */ 27620Buttons.buttonSelector = function ( insts, selector ) 27621{ 27622 var ret = []; 27623 var nodeBuilder = function ( a, buttons, baseIdx ) { 27624 var button; 27625 var idx; 27626 27627 for ( var i=0, ien=buttons.length ; i<ien ; i++ ) { 27628 button = buttons[i]; 27629 27630 if ( button ) { 27631 idx = baseIdx !== undefined ? 27632 baseIdx+i : 27633 i+''; 27634 27635 a.push( { 27636 node: button.node, 27637 name: button.conf.name, 27638 idx: idx 27639 } ); 27640 27641 if ( button.buttons ) { 27642 nodeBuilder( a, button.buttons, idx+'-' ); 27643 } 27644 } 27645 } 27646 }; 27647 27648 var run = function ( selector, inst ) { 27649 var i, ien; 27650 var buttons = []; 27651 nodeBuilder( buttons, inst.s.buttons ); 27652 27653 var nodes = $.map( buttons, function (v) { 27654 return v.node; 27655 } ); 27656 27657 if ( Array.isArray( selector ) || selector instanceof $ ) { 27658 for ( i=0, ien=selector.length ; i<ien ; i++ ) { 27659 run( selector[i], inst ); 27660 } 27661 return; 27662 } 27663 27664 if ( selector === null || selector === undefined || selector === '*' ) { 27665 // Select all 27666 for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
27667 ret.push( { 27668 inst: inst, 27669 node: buttons[i].node 27670 } ); 27671 } 27672 } 27673 else if ( typeof selector === 'number' ) { 27674 // Main button index selector 27675 ret.push( { 27676 inst: inst, 27677 node: inst.s.buttons[ selector ].node 27678 } ); 27679 } 27680 else if ( typeof selector === 'string' ) { 27681 if ( selector.indexOf( ',' ) !== -1 ) { 27682 // Split 27683 var a = selector.split(','); 27684 27685 for ( i=0, ien=a.length ; i<ien ; i++ ) { 27686 run( a[i].trim(), inst ); 27687 } 27688 } 27689 else if ( selector.match( /^\d+(\-\d+)*$/ ) ) { 27690 // Sub-button index selector 27691 var indexes = $.map( buttons, function (v) { 27692 return v.idx; 27693 } ); 27694 27695 ret.push( { 27696 inst: inst, 27697 node: buttons[ $.inArray( selector, indexes ) ].node 27698 } ); 27699 } 27700 else if ( selector.indexOf( ':name' ) !== -1 ) { 27701 // Button name selector 27702 var name = selector.replace( ':name', '' ); 27703 27704 for ( i=0, ien=buttons.length ; i<ien ; i++ ) { 27705 if ( buttons[i].name === name ) { 27706 ret.push( { 27707 inst: inst, 27708 node: buttons[i].node 27709 } ); 27710 } 27711 } 27712 } 27713 else { 27714 // jQuery selector on the nodes 27715 $( nodes ).filter( selector ).each( function () { 27716 ret.push( { 27717 inst: inst, 27718 node: this 27719 } ); 27720 } ); 27721 } 27722 } 27723 else if ( typeof selector === 'object' && selector.nodeName ) { 27724 // Node selector 27725 var idx = $.inArray( selector, nodes ); 27726 27727 if ( idx !== -1 ) { 27728 ret.push( { 27729 inst: inst, 27730 node: nodes[ idx ] 27731 } ); 27732 } 27733 } 27734 }; 27735 27736 27737 for ( var i=0, ien=insts.length ; i<ien ; i++ ) { 27738 var inst = insts[i]; 27739 27740 run( selector, inst ); 27741 } 27742 27743 return ret; 27744}; 27745 27746/** 27747 * Default function used for formatting output data. 27748 * @param {*} str Data to strip 27749 */ 27750Buttons.stripData = function ( str, config ) { 27751 if ( typeof str !== 'string' ) { 27752 return str; 27753 } 27754 27755 // Always remove script tags 27756 str = str.replace( /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '' ); 27757 27758 // Always remove comments 27759 str = str.replace( /<!\-\-.*?\-\->/g, '' ); 27760 27761 if ( ! config || config.stripHtml ) { 27762 str = str.replace( /<[^>]*>/g, '' ); 27763 } 27764 27765 if ( ! config || config.trim ) { 27766 str = str.replace( /^\s+|\s+$/g, '' ); 27767 } 27768 27769 if ( ! config || config.stripNewlines ) { 27770 str = str.replace( /\n/g, ' ' ); 27771 } 27772 27773 if ( ! config || config.decodeEntities ) { 27774 _exportTextarea.innerHTML = str; 27775 str = _exportTextarea.value; 27776 } 27777 27778 return str; 27779}; 27780 27781 27782/** 27783 * Buttons defaults. For full documentation, please refer to the docs/option 27784 * directory or the DataTables site. 27785 * @type {Object} 27786 * @static 27787 */ 27788Buttons.defaults = { 27789 buttons: [ 'copy', 'excel', 'csv', 'pdf', 'print' ], 27790 name: 'main', 27791 tabIndex: 0, 27792 dom: { 27793 container: { 27794 tag: 'div', 27795 className: 'dt-buttons' 27796 }, 27797 collection: { 27798 tag: 'div', 27799 className: '' 27800 }, 27801 button: { 27802 tag: 'button', 27803 className: 'dt-button', 27804 active: 'active', 27805 disabled: 'disabled' 27806 }, 27807 buttonLiner: { 27808 tag: 'span', 27809 className: '' 27810 } 27811 } 27812}; 27813 27814/** 27815 * Version information 27816 * @type {string} 27817 * @static 27818 */ 27819Buttons.version = '1.7.1'; 27820 27821 27822$.extend( _dtButtons, { 27823 collection: { 27824 text: function ( dt ) { 27825 return dt.i18n( 'buttons.collection', 'Collection' ); 27826 }, 27827 className: 'buttons-collection', 27828 init: function ( dt, button, config ) { 27829 button.attr( 'aria-expanded', false ); 27830 }, 27831 action: function ( e, dt, button, config ) { 27832 e.stopPropagation(); 27833 27834 if ( config._collection.parents('body').length ) { 27835 this.popover(false, config); 27836 } 27837 else { 27838 this.popover(config._collection, config); 27839 } 27840 }, 27841 attr: { 27842 'aria-haspopup': true 27843 } 27844 // Also the popover options, defined in Buttons.popover 27845 }, 27846 copy: function ( dt, conf ) { 27847 if ( _dtButtons.copyHtml5 ) { 27848 return 'copyHtml5'; 27849 } 27850 }, 27851 csv: function ( dt, conf ) { 27852 if ( _dtButtons.csvHtml5 && _dtButtons.csvHtml5.available( dt, conf ) ) { 27853 return 'csvHtml5'; 27854 } 27855 }, 27856 excel: function ( dt, conf ) { 27857 if ( _dtButtons.excelHtml5 && _dtButtons.excelHtml5.available( dt, conf ) ) { 27858 return 'excelHtml5'; 27859 } 27860 }, 27861 pdf: function ( dt, conf ) { 27862 if ( _dtButtons.pdfHtml5 && _dtButtons.pdfHtml5.available( dt, conf ) ) { 27863 return 'pdfHtml5'; 27864 } 27865 }, 27866 pageLength: function ( dt ) { 27867 var lengthMenu = dt.settings()[0].aLengthMenu; 27868 var vals = []; 27869 var lang = []; 27870 var text = function ( dt ) { 27871 return dt.i18n( 'buttons.pageLength', { 27872 "-1": 'Show all rows', 27873 _: 'Show %d rows' 27874 }, dt.page.len() ); 27875 }; 27876
27877 // Support for DataTables 1.x 2D array 27878 if (Array.isArray( lengthMenu[0] )) { 27879 vals = lengthMenu[0]; 27880 lang = lengthMenu[1]; 27881 } 27882 else { 27883 for (var i=0 ; i<lengthMenu.length ; i++) { 27884 var option = lengthMenu[i]; 27885 27886 // Support for DataTables 2 object in the array 27887 if ($.isPlainObject(option)) { 27888 vals.push(option.value); 27889 lang.push(option.label); 27890 } 27891 else { 27892 vals.push(option); 27893 lang.push(option); 27894 } 27895 } 27896 } 27897 27898 return { 27899 extend: 'collection', 27900 text: text, 27901 className: 'buttons-page-length', 27902 autoClose: true, 27903 buttons: $.map( vals, function ( val, i ) { 27904 return { 27905 text: lang[i], 27906 className: 'button-page-length', 27907 action: function ( e, dt ) { 27908 dt.page.len( val ).draw(); 27909 }, 27910 init: function ( dt, node, conf ) { 27911 var that = this; 27912 var fn = function () { 27913 that.active( dt.page.len() === val ); 27914 }; 27915 27916 dt.on( 'length.dt'+conf.namespace, fn ); 27917 fn(); 27918 }, 27919 destroy: function ( dt, node, conf ) { 27920 dt.off( 'length.dt'+conf.namespace ); 27921 } 27922 }; 27923 } ), 27924 init: function ( dt, node, conf ) { 27925 var that = this; 27926 dt.on( 'length.dt'+conf.namespace, function () { 27927 that.text( conf.text ); 27928 } ); 27929 }, 27930 destroy: function ( dt, node, conf ) { 27931 dt.off( 'length.dt'+conf.namespace ); 27932 } 27933 }; 27934 } 27935} ); 27936 27937 27938/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 27939 * DataTables API 27940 * 27941 * For complete documentation, please refer to the docs/api directory or the 27942 * DataTables site 27943 */ 27944 27945// Buttons group and individual button selector 27946DataTable.Api.register( 'buttons()', function ( group, selector ) { 27947 // Argument shifting 27948 if ( selector === undefined ) { 27949 selector = group; 27950 group = undefined; 27951 } 27952 27953 this.selector.buttonGroup = group; 27954 27955 var res = this.iterator( true, 'table', function ( ctx ) { 27956 if ( ctx._buttons ) { 27957 return Buttons.buttonSelector( 27958 Buttons.instanceSelector( group, ctx._buttons ), 27959 selector 27960 ); 27961 } 27962 }, true ); 27963 27964 res._groupSelector = group; 27965 return res; 27966} ); 27967 27968// Individual button selector 27969DataTable.Api.register( 'button()', function ( group, selector ) { 27970 // just run buttons() and truncate 27971 var buttons = this.buttons( group, selector ); 27972 27973 if ( buttons.length > 1 ) { 27974 buttons.splice( 1, buttons.length ); 27975 } 27976 27977 return buttons; 27978} ); 27979 27980// Active buttons 27981DataTable.Api.registerPlural( 'buttons().active()', 'button().active()', function ( flag ) { 27982 if ( flag === undefined ) { 27983 return this.map( function ( set ) { 27984 return set.inst.active( set.node ); 27985 } ); 27986 } 27987 27988 return this.each( function ( set ) { 27989 set.inst.active( set.node, flag ); 27990 } ); 27991} ); 27992 27993// Get / set button action 27994DataTable.Api.registerPlural( 'buttons().action()', 'button().action()', function ( action ) { 27995 if ( action === undefined ) { 27996 return this.map( function ( set ) { 27997 return set.inst.action( set.node ); 27998 } ); 27999 } 28000 28001 return this.each( function ( set ) { 28002 set.inst.action( set.node, action ); 28003 } ); 28004} ); 28005 28006// Enable / disable buttons 28007DataTable.Api.register( ['buttons().enable()', 'button().enable()'], function ( flag ) { 28008 return this.each( function ( set ) { 28009 set.inst.enable( set.node, flag ); 28010 } ); 28011} ); 28012 28013// Disable buttons 28014DataTable.Api.register( ['buttons().disable()', 'button().disable()'], function () { 28015 return this.each( function ( set ) { 28016 set.inst.disable( set.node ); 28017 } ); 28018} ); 28019 28020// Get button nodes 28021DataTable.Api.registerPlural( 'buttons().nodes()', 'button().node()', function () { 28022 var jq = $(); 28023 28024 // jQuery will automatically reduce duplicates to a single entry 28025 $( this.each( function ( set ) { 28026 jq = jq.add( set.inst.node( set.node ) ); 28027 } ) ); 28028 28029 return jq; 28030} ); 28031 28032// Get / set button processing state 28033DataTable.Api.registerPlural( 'buttons().processing()', 'button().processing()', function ( flag ) { 28034 if ( flag === undefined ) { 28035 return this.map( function ( set ) { 28036 return set.inst.processing( set.node ); 28037 } ); 28038 } 28039 28040 return this.each( function ( set ) { 28041 set.inst.processing( set.node, flag ); 28042 } ); 28043} ); 28044 28045// Get / set button text (i.e. the button labels) 28046DataTable.Api.registerPlural( 'buttons().text()', 'button().text()', function ( label ) { 28047 if ( label === undefined ) { 28048 return this.map( function ( set ) { 28049 return set.inst.text( set.node ); 28050 } ); 28051 } 28052 28053 return this.each( function ( set ) { 28054 set.inst.text( set.node, label ); 28055 } ); 28056} ); 28057 28058// Trigger a button's action 28059DataTable.Api.registerPlural( 'buttons().trigger()', 'button().trigger()', function () { 28060 return this.each( function ( set ) {
28061 set.inst.node( set.node ).trigger( 'click' ); 28062 } ); 28063} ); 28064 28065// Button resolver to the popover 28066DataTable.Api.register( 'button().popover()', function (content, options) { 28067 return this.map( function ( set ) { 28068 return set.inst._popover( content, this.button(this[0].node), options ); 28069 } ); 28070} ); 28071 28072// Get the container elements 28073DataTable.Api.register( 'buttons().containers()', function () { 28074 var jq = $(); 28075 var groupSelector = this._groupSelector; 28076 28077 // We need to use the group selector directly, since if there are no buttons 28078 // the result set will be empty 28079 this.iterator( true, 'table', function ( ctx ) { 28080 if ( ctx._buttons ) { 28081 var insts = Buttons.instanceSelector( groupSelector, ctx._buttons ); 28082 28083 for ( var i=0, ien=insts.length ; i<ien ; i++ ) { 28084 jq = jq.add( insts[i].container() ); 28085 } 28086 } 28087 } ); 28088 28089 return jq; 28090} ); 28091 28092DataTable.Api.register( 'buttons().container()', function () { 28093 // API level of nesting is `buttons()` so we can zip into the containers method 28094 return this.containers().eq(0); 28095} ); 28096 28097// Add a new button 28098DataTable.Api.register( 'button().add()', function ( idx, conf ) { 28099 var ctx = this.context; 28100 28101 // Don't use `this` as it could be empty - select the instances directly 28102 if ( ctx.length ) { 28103 var inst = Buttons.instanceSelector( this._groupSelector, ctx[0]._buttons ); 28104 28105 if ( inst.length ) { 28106 inst[0].add( conf, idx ); 28107 } 28108 } 28109 28110 return this.button( this._groupSelector, idx ); 28111} ); 28112 28113// Destroy the button sets selected 28114DataTable.Api.register( 'buttons().destroy()', function () { 28115 this.pluck( 'inst' ).unique().each( function ( inst ) { 28116 inst.destroy(); 28117 } ); 28118 28119 return this; 28120} ); 28121 28122// Remove a button 28123DataTable.Api.registerPlural( 'buttons().remove()', 'buttons().remove()', function () { 28124 this.each( function ( set ) { 28125 set.inst.remove( set.node ); 28126 } ); 28127 28128 return this; 28129} ); 28130 28131// Information box that can be used by buttons 28132var _infoTimer; 28133DataTable.Api.register( 'buttons.info()', function ( title, message, time ) { 28134 var that = this; 28135 28136 if ( title === false ) { 28137 this.off('destroy.btn-info'); 28138 _fadeOut( 28139 $('#datatables_buttons_info'), 28140 400, 28141 function () { 28142 $(this).remove(); 28143 } 28144 ); 28145 clearTimeout( _infoTimer ); 28146 _infoTimer = null; 28147 28148 return this; 28149 } 28150 28151 if ( _infoTimer ) { 28152 clearTimeout( _infoTimer ); 28153 } 28154 28155 if ( $('#datatables_buttons_info').length ) { 28156 $('#datatables_buttons_info').remove(); 28157 } 28158 28159 title = title ? '<h2>'+title+'</h2>' : ''; 28160 28161 _fadeIn( 28162 $('<div id="datatables_buttons_info" class="dt-button-info"/>') 28163 .html( title ) 28164 .append( $('<div/>')[ typeof message === 'string' ? 'html' : 'append' ]( message ) ) 28165 .css( 'display', 'none' ) 28166 .appendTo( 'body' ) 28167 ); 28168 28169 if ( time !== undefined && time !== 0 ) { 28170 _infoTimer = setTimeout( function () { 28171 that.buttons.info( false ); 28172 }, time ); 28173 } 28174 28175 this.on('destroy.btn-info', function () { 28176 that.buttons.info(false); 28177 }); 28178 28179 return this; 28180} ); 28181 28182// Get data from the table for export - this is common to a number of plug-in 28183// buttons so it is included in the Buttons core library 28184DataTable.Api.register( 'buttons.exportData()', function ( options ) { 28185 if ( this.context.length ) { 28186 return _exportData( new DataTable.Api( this.context[0] ), options ); 28187 } 28188} ); 28189 28190// Get information about the export that is common to many of the export data 28191// types (DRY) 28192DataTable.Api.register( 'buttons.exportInfo()', function ( conf ) { 28193 if ( ! conf ) { 28194 conf = {}; 28195 } 28196 28197 return { 28198 filename: _filename( conf ), 28199 title: _title( conf ), 28200 messageTop: _message(this, conf.message || conf.messageTop, 'top'), 28201 messageBottom: _message(this, conf.messageBottom, 'bottom') 28202 }; 28203} ); 28204 28205 28206 28207/** 28208 * Get the file name for an exported file. 28209 * 28210 * @param {object} config Button configuration 28211 * @param {boolean} incExtension Include the file name extension 28212 */ 28213var _filename = function ( config ) 28214{ 28215 // Backwards compatibility 28216 var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined && config.title !== null && config.title !== '' ? 28217 config.title : 28218 config.filename; 28219 28220 if ( typeof filename === 'function' ) { 28221 filename = filename(); 28222 } 28223 28224 if ( filename === undefined || filename === null ) { 28225 return null; 28226 } 28227 28228 if ( filename.indexOf( '*' ) !== -1 ) { 28229 filename = filename.replace( '*', $('head > title').text() ).trim(); 28230 } 28231 28232 // Strip characters which the OS will object to 28233 filename = filename.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, ""); 28234 28235 var extension = _stringOrFunction( config.extension ); 28236 if ( ! extension ) { 28237 extension = ''; 28238 } 28239 28240 return filename + extension; 28241}; 28242 28243/** 28244 * Simply utility method to allow parameters to be given as a function 28245 * 28246 * @param {undefined|string|function} option Option 28247 * @return {null|string} Resolved value 28248 */ 28249var _stringOrFunction = function ( option ) 28250{ 28251 if ( option === null || option === undefined ) { 28252 return null; 28253 } 28254 else if ( typeof option === 'function' ) { 28255 return option(); 28256 } 28257 return option; 28258}; 28259 28260/** 28261 * Get the title for an exported file. 28262 * 28263 * @param {object} config Button configuration 28264 */ 28265var _title = function ( config ) 28266{ 28267 var title = _stringOrFunction( config.title ); 28268 28269 return title === null ? 28270 null : title.indexOf( '*' ) !== -1 ? 28271 title.replace( '*', $('head > title').text() || 'Exported data' ) : 28272 title; 28273}; 28274 28275var _message = function ( dt, option, position ) 28276{ 28277 var message = _stringOrFunction( option ); 28278 if ( message === null ) { 28279 return null; 28280 } 28281 28282 var caption = $('caption', dt.table().container()).eq(0); 28283 if ( message === '*' ) { 28284 var side = caption.css( 'caption-side' ); 28285 if ( side !== position ) { 28286 return null; 28287 } 28288 28289 return caption.length ? 28290 caption.text() : 28291 ''; 28292 } 28293 28294 return message; 28295}; 28296 28297 28298 28299 28300var _exportTextarea = $('<textarea/>')[0]; 28301var _exportData = function ( dt, inOpts ) 28302{ 28303 var config = $.extend( true, {}, { 28304 rows: null, 28305 columns: '', 28306 modifier: { 28307 search: 'applied', 28308 order: 'applied' 28309 }, 28310 orthogonal: 'display', 28311 stripHtml: true, 28312 stripNewlines: true, 28313 decodeEntities: true, 28314 trim: true, 28315 format: { 28316 header: function ( d ) {
28317 return Buttons.stripData( d, config ); 28318 }, 28319 footer: function ( d ) { 28320 return Buttons.stripData( d, config ); 28321 }, 28322 body: function ( d ) { 28323 return Buttons.stripData( d, config ); 28324 } 28325 }, 28326 customizeData: null 28327 }, inOpts ); 28328 28329 var header = dt.columns( config.columns ).indexes().map( function (idx) { 28330 var el = dt.column( idx ).header(); 28331 return config.format.header( el.innerHTML, idx, el ); 28332 } ).toArray(); 28333 28334 var footer = dt.table().footer() ? 28335 dt.columns( config.columns ).indexes().map( function (idx) { 28336 var el = dt.column( idx ).footer(); 28337 return config.format.footer( el ? el.innerHTML : '', idx, el ); 28338 } ).toArray() : 28339 null; 28340 28341 // If Select is available on this table, and any rows are selected, limit the export 28342 // to the selected rows. If no rows are selected, all rows will be exported. Specify 28343 // a `selected` modifier to control directly. 28344 var modifier = $.extend( {}, config.modifier ); 28345 if ( dt.select && typeof dt.select.info === 'function' && modifier.selected === undefined ) { 28346 if ( dt.rows( config.rows, $.extend( { selected: true }, modifier ) ).any() ) { 28347 $.extend( modifier, { selected: true } ) 28348 } 28349 } 28350 28351 var rowIndexes = dt.rows( config.rows, modifier ).indexes().toArray(); 28352 var selectedCells = dt.cells( rowIndexes, config.columns ); 28353 var cells = selectedCells 28354 .render( config.orthogonal ) 28355 .toArray(); 28356 var cellNodes = selectedCells 28357 .nodes() 28358 .toArray(); 28359 28360 var columns = header.length; 28361 var rows = columns > 0 ? cells.length / columns : 0; 28362 var body = []; 28363 var cellCounter = 0; 28364 28365 for ( var i=0, ien=rows ; i<ien ; i++ ) { 28366 var row = [ columns ]; 28367 28368 for ( var j=0 ; j<columns ; j++ ) { 28369 row[j] = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] ); 28370 cellCounter++; 28371 } 28372 28373 body[i] = row; 28374 } 28375 28376 var data = { 28377 header: header, 28378 footer: footer, 28379 body: body 28380 }; 28381 28382 if ( config.customizeData ) { 28383 config.customizeData( data ); 28384 } 28385 28386 return data; 28387}; 28388 28389 28390/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 28391 * DataTables interface 28392 */ 28393 28394// Attach to DataTables objects for global access 28395$.fn.dataTable.Buttons = Buttons; 28396$.fn.DataTable.Buttons = Buttons; 28397 28398 28399 28400// DataTables creation - check if the buttons have been defined for this table, 28401// they will have been if the `B` option was used in `dom`, otherwise we should 28402// create the buttons instance here so they can be inserted into the document 28403// using the API. Listen for `init` for compatibility with pre 1.10.10, but to 28404// be removed in future. 28405$(document).on( 'init.dt plugin-init.dt', function (e, settings) { 28406 if ( e.namespace !== 'dt' ) { 28407 return; 28408 } 28409 28410 var opts = settings.oInit.buttons || DataTable.defaults.buttons; 28411 28412 if ( opts && ! settings._buttons ) { 28413 new Buttons( settings, opts ).container(); 28414 } 28415} ); 28416 28417function _init ( settings, options ) { 28418 var api = new DataTable.Api( settings ); 28419 var opts = options 28420 ? options 28421 : api.init().buttons || DataTable.defaults.buttons; 28422 28423 return new Buttons( api, opts ).container(); 28424} 28425 28426// DataTables `dom` feature option 28427DataTable.ext.feature.push( { 28428 fnInit: _init, 28429 cFeature: "B" 28430} ); 28431 28432// DataTables 2 layout feature 28433if ( DataTable.ext.features ) { 28434 DataTable.ext.features.register( 'buttons', _init ); 28435} 28436 28437 28438return Buttons; 28439})); 28440 28441 28442/***/ }), 28443/* 5 */, 28444/* 6 */, 28445/* 7 */ 28446/***/ (function(module, exports, __webpack_require__) { 28447 28448"use strict"; 28449 28450 28451__webpack_require__(31); 28452 28453var _frontendExporter = __webpack_require__(8); 28454 28455var _frontendExporter2 = _interopRequireDefault(_frontendExporter); 28456 28457var _reportingDashboard = __webpack_require__(9); 28458 28459var _reportingDashboard2 = _interopRequireDefault(_reportingDashboard); 28460 28461function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28462 28463// import loadQuizData from './quiz-data'; 28464 28465var exporter = new _frontendExporter2.default(); 28466// var data_loader = new loadQuizData(); 28467// cspell:ignore livesearch . 28468var dashboard_instance = new _reportingDashboard2.default(); 28469 28470exporter.downloadReport('.qre-export'); 28471// data_loader.onQuizLoad( '.qre_quiz_data_container', '.quiz_load' ); 28472// data_loader.onUserChange( '.UserID' ); 28473 28474/*New Dashboard Logic*/ 28475// dashboard_instance.toggleDuration( 28476// '.quiz-report-filters', 28477// '.date-filter input[type=checkbox]' 28478// ); 28479// dashboard_instance.initDatepicker( 28480// ['.quiz-report-filters input[name=from_date]', '.quiz-report-filters input[name=to_date]'] ); 28481dashboard_instance.livesearch('.quiz-report-filters #qre-search-field', '.search_result_type', '.search_result_id'); 28482dashboard_instance.showDatatable('#qre_summarized_data'); 28483dashboard_instance.paginateReportsTable('.pagination-form', 'select.limit', '.pagination-section input.page', '.pagination-section button.previous-page', '.pagination-section button.next-page'); 28484// dashboard_instance.customDatepicker( 28485// ['.custom-report-filters input[name=enrollment_from]', '.custom-report-filters input[name=enrollment_to]'] ); 28486// dashboard_instance.customDatepicker( 28487// ['.custom-report-filters input[name=completion_from]', '.custom-report-filters input[name=completion_to]'] ); 28488// dashboard_instance.saveCustomReports( '.custom-report-filters', '.s
28488ave_config' ); 28489// dashboard_instance.toggleFilterGroups( '.custom-report-filters', '.section-control' ); 28490// dashboard_instance.previewCustomReport( '.custom-report-filters', '.preview-data', '.save_config' ); 28491// dashboard_instance.enableGenerateButton( '.custom-report-filters', '.preview-data' ); 28492// dashboard_instance.onScrollStickyElement(); 28493dashboard_instance.toggleHiddenRow('#custom-reports', '.accordion-target', '.accordion-trigger'); 28494dashboard_instance.showBulkExportModal('.wrld-bulk-export', '.button-bulk-export'); 28495 28496/***/ }), 28497/* 8 */ 28498/***/ (function(module, exports, __webpack_require__) { 28499 28500"use strict"; 28501 28502 28503Object.defineProperty(exports, "__esModule", { 28504 value: true 28505}); 28506 28507var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 28508 28509function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 28510 28511// cspell:ignore . 28512/** 28513 * This class is used to handle the functionality of exporting in the website frontend. 28514 */ 28515/* globals qre_export_obj: false */ 28516var frontendExporter = function () { 28517 function frontendExporter() { 28518 _classCallCheck(this, frontendExporter); 28519 } 28520 /** 28521 * This method is used to handle the export feature in the website frontend. 28522 * @param {string} selector The selector of the download link. 28523 */ 28524 28525 28526 _createClass(frontendExporter, [{ 28527 key: 'downloadReport', 28528 value: function downloadReport(selector) { 28529 var instance = this; 28530 jQuery('body').on('click', selector, function (event) { 28531 event.preventDefault(); 28532 var $self = jQuery(this); 28533 var ref_id = $self.attr('data-ref_id'); 28534 var format = ''; 28535 if ($self.hasClass('qre-download-csv')) { 28536 format = 'csv'; 28537 } 28538 if ($self.hasClass('qre-download-xlsx')) { 28539 format = 'xlsx'; 28540 } 28541 jQuery('#qre_exp_form_' + qre_export_obj.quiz_export_nonce).remove(); // removes previously generated form 28542 jQuery('#qre_error').remove(); // removes previously generated errors 28543 if (ref_id !== '' && ref_id !== undefined) { 28544 var refs = ref_id.split(','); 28545 if (refs.length > 1) { 28546 if (typeof jQuery('.entry-content').block !== 'undefined') { 28547 jQuery('.entry-content').block({ 28548 message: '<h4>Processing...</h4>', 28549 css: { border: '3px solid #a00' } 28550 }); 28551 } 28552 window.prepareZipFile.prototype.prepareZip(format, ref_id, 0, qre_export_obj.ajax_url, qre_export_obj.quiz_export_nonce); 28553 } else { 28554 $self.find('form').remove(); 28555 var html_str = '<form id="qre_exp_form_' + qre_export_obj.quiz_export_nonce + '" method="post" action="" target="_blank" style="display:none;">' + '<input name="file_format" type="hidden" value="' + format + '">' + '<input name="ref_id" type="hidden" value="' + ref_id + '">' + '<input name="quiz_export_nonce" type="hidden" value="' + qre_export_obj.quiz_export_nonce + '">' + '</form>'; 28556 $self.append(html_str); 28557 $self.find('form').submit(); 28558 jQuery('#qre_loader').remove(); 28559 } 28560 } 28561 }); 28562 } 28563 }]); 28564 28565 return frontendExporter; 28566}(); 28567 28568exports.default = frontendExporter; 28569 28570/***/ }), 28571/* 9 */ 28572/***/ (function(module, exports, __webpack_require__) { 28573 28574"use strict"; 28575 28576 28577Object.defineProperty(exports, "__esModule", { 28578 value: true 28579}); 28580 28581var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 28582 28583var _resultFilters = __webpack_require__(10); 28584 28585var _resultFilters2 = _interopRequireDefault(_resultFilters); 28586 28587var _customReports = __webpack_require__(11); 28588 28589var _customReports2 = _interopRequireDefault(_customReports); 28590 28591__webpack_require__(4); 28592 28593__webpack_require__(12); 28594 28595function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28596 28597function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 28598 28599// cspell:ignore livesearch lTfgtip . 28600/** 28601 * This class iz used to load quiz data and other UI events related to the shortcode. 28602 */ 28603/*globals quiz_statistics_data:false, qre_export_obj: false*/ 28604window.$ = jQuery; 28605// var dt2 = require('datatables.net-buttons'); 28606var dt = __webpack_require__(13); 28607var JSZip = __webpack_require__(16); 28608window.$.fn.DataTable = dt; 28609window.$.fn.DataTable.Buttons.jszip(JSZip); 28610 28611jQuery.fn.outerHTML = function () { 28612 return jQuery('<div />').append(this.eq(0).clone()).html(); 28613}; 28614 28615var reportingDashboard = function () { 28616 function reportingDashboard() { 28617 _classCallCheck(this, reportingDashboard); 28618 28619 this.result_filters = new _resultFilters2.default(); 28620 this.custom_reports = new _customReports2.default(); 28621 this.quiz_reports_table = null; 28622 this.custom_reports_table = null; 28623 } 28624 28625 _createClass(reportingDashboard, [{ 28626 key: 'toggleDuration', 28627 value: function toggleDuration(container, selector) { 28628 this.result_filters.toggle(container, selector); 28629 } 28630 }, { 28631 key: 'initDatepicker', 28632 value: function initDatepicker(selectors) { 28633 this.result_filters.datepicker_init(selectors); 28634 } 28635 }, { 28636 key: 'livesearch', 28637 value: function livesearch(selector, type_selector, id_selector) { 28638 this.result_filters.search(selector); 28639 this.result_filters.select_result(selector, type_selector, id_selector); 28640 this.result_filters.reset_search(selector, type_selector, id_selector); 28641 } 28642 }, { 28643 key: 'showDatatable', 28644 value: function showDatatable(selector) { 28645 var instance = this; 28646 jQuery(document).ready(function () { 28647 if (typeof quiz_statistics_data === 'undefined') { 28648 return; 28649 } 28650 var $quiz_title = null; 28651 var $quiz_title_text = ''; 28652 var $user_name = null; 28653 var $user_name_text = ''; 28654 for (var i = 0; i < quiz_statistics_data.data.length; i++) { 28655 if (jQuery(window).width() < 1500) { 28656 $quiz_title = jQuery(quiz_statistics_data.data[i].quiz_title); 28657 $quiz_title_text = $quiz_title.text().substring(0, 30); 28658 if ($quiz_title.text().length > 30) { 28659 $quiz_title_text += '...'; 28660 } 28661 $quiz_title.text($quiz_title_text); 28662 quiz_statistics_data.data[i].quiz_title = $quiz_title.outerHTML(); 28663 $user_name = jQuery(quiz_statistics_data.data[i].user_name); 28664 $user_name_text = $user_name.text().substring(0, 30); 28665 if ($user_name.text().length > 30) { 28666 $user_name_text += '...'; 28667 } 28668 $user_name.text($user_name_text); 28669 quiz_statistics_data.data[i].user_name = $user_name.outerHTML(); 28670 } 28671 quiz_statistics_data.data[i].index = i + 1; 28672 } 28673 instance.quiz_reports_table = jQuery(selector).DataTable({ 28674 paging: false, 28675 ordering: false, 28676 searching: false, 28677 info: false, 28678 responsive: false, 28679 data: quiz_statistics_data.data, 28680 columns: [{ data: 'index', visible: true }, { data: 'quiz_title', visible: true }, { data: 'user_name', visible: true }, { data: 'date_attempt', visible: true }, { data: 'score', visible: true }, { data: 'time_taken', visible: true }, { data: 'link', visible: true }], 28681 columnDefs: [{ 28682 targets: [0, 3, 4, 5, 6], 28683 className: 'dt-center' 28684 }, {
28685 targets: [1, 2], 28686 className: 'dt-left' 28687 }], 28688 language: { 28689 emptyTable: quiz_statistics_data.no_data 28690 } 28691 }); 28692 }); 28693 } 28694 }, { 28695 key: 'paginateReportsTable', 28696 value: function paginateReportsTable(pagination_form, limit_selector, page_number_selector, previous_page_btn, next_page_button) { 28697 var instance = this; 28698 jQuery(document).ready(function () { 28699 instance.result_filters.change_entry_count(pagination_form, limit_selector); 28700 instance.result_filters.change_page_number(pagination_form, page_number_selector, previous_page_btn, next_page_button); 28701 }); 28702 } 28703 }, { 28704 key: 'customDatepicker', 28705 value: function customDatepicker(selectors) { 28706 this.custom_reports.datepicker_init(selectors); 28707 } 28708 }, { 28709 key: 'saveCustomReports', 28710 value: function saveCustomReports(container, button) { 28711 var instance = this; 28712 jQuery(document).ready(function () { 28713 instance.custom_reports.save_config(container, button); 28714 }); 28715 } 28716 }, { 28717 key: 'toggleFilterGroups', 28718 value: function toggleFilterGroups(container, button) { 28719 var instance = this; 28720 jQuery(document).ready(function () { 28721 instance.custom_reports.toggle_filter_group(container, button); 28722 }); 28723 } 28724 }, { 28725 key: 'previewCustomReport', 28726 value: function previewCustomReport(container, preview_button, save_button) { 28727 var instance = this; 28728 jQuery(document).ready(function () { 28729 instance.custom_reports.fetch_data(preview_button, save_button); 28730 jQuery(document).on('custom_report_created', function (event, dat) { 28731 /*if ( jQuery.fn.DataTable.isDataTable( '#custom-reports' ) ) { 28732 instance.custom_reports_table.fnDestroy(); 28733 column_slugs = []; 28734 jQuery( container ).find( 'input[type="checkbox"]' ).each( function( ind, ele ) { 28735 if ( jQuery( ele ).is( ':checked' ) ) { 28736 if ( jQuery( '#custom-reports' ).find( 'th[data-column=' + jQuery( ele ).attr( 'name' ) + ']' ).length === 0 ) { 28737 jQuery( 'table thead tr' ).append( 28738 '<th data-column="' + jQuery( ele ).attr( 'name' ) + '">' + 28739 jQuery( 'label[for=' + jQuery( ele ).attr( 'name' ) + ']' ).text() + 28740 '</th>' 28741 ); 28742 } 28743 } else { 28744 if ( jQuery( '#custom-reports' ).find( 'th[data-column=' + jQuery( ele ).attr( 'name' ) + ']' ).length > 0 ) { 28745 var $table_column = jQuery( 'table th[data-column="' + jQuery( ele ).attr( 'name' ) + '"]' ); 28746 var cell_index = $table_column.index(); 28747 $table_column.closest('table').find('tr').each(function() { 28748 if ( typeof this.cells[ cell_index ] !== 'undefined' ) { 28749 this.removeChild( this.cells[ cell_index ] ); 28750 } 28751 }); 28752 } 28753 } 28754 } ); 28755 }*/ 28756 jQuery('#custom-reports').show(); 28757 /*var headings = jQuery('#custom-reports th'); 28758 var column_slugs = []; 28759 headings.each(function(index, ele){ 28760 column_slugs.push({ data: jQuery(ele).attr('data-column'), className: 'px200' }); 28761 }); 28762 instance.custom_reports_table = jQuery( '#custom-reports' ).DataTable( 28763 { 28764 responsive: true, 28765 dom: '<"html5buttons"B>lTfgtip', 28766 buttons: [ 28767 { extend: 'csv', text: qre_export_obj.download_csv_text}, 28768 { extend: 'excel', text: qre_export_obj.download_xls_text }, 28769 ], 28770 'bDestroy': true, 28771 data: dat, 28772 columns: column_slugs, 28773 destroy: true, 28774 }); 28775 jQuery('.dt-buttons').appendTo( '.custom-report-buttons' );*/ 28776 }); 28777 }); 28778 } 28779 }, { 28780 key: 'enableGenerateButton', 28781 value: function enableGenerateButton(container, preview_button) { 28782 var instance = this; 28783 jQuery(container).on('change', 'select', function () { 28784 jQuery(preview_button).css('visibility', 'visible'); 28785 }); 28786 jQuery(container).on('change click', 'input[type=checkbox], input[type=text]', function () { 28787 jQuery(preview_button).css('visibility', 'visible'); 28788 }); 28789 /*jQuery( container ).on( 'change', 'input[type=checkbox]', function() { 28790 if ( jQuery( this ).is( ':checked' ) ) { 28791 if ( ! jQuery.fn.DataTable.isDataTable( '#custom-reports' ) ) { 28792 jQuery( 'table thead tr' ).append( 28793 '<th data-column="' + jQuery( this ).attr( 'name' ) + '">' + 28794 jQuery( 'label[for=' + jQuery( this ).attr( 'name' ) + ']' ).text() + 28795 '</th>' 28796 ); 28797 } 28798 } else { 28799 if ( ! jQuery.fn.DataTable.isDataTable( '#custom-reports' ) ) { 28800 var $table_column = jQuery( 'table th[data-column="' + jQuery(this).attr( 'name' ) + '"]' ); 28801 var cell_index = $table_column.index(); 28802 $table_column.closest('table').find('tr').each(function() { 28803 if ( typeof this.cells[ cell_index ] !== 'undefined' ) { 28804 this.removeChild( this.cells[ cell_index ] ); 28805 } 28806 }); 28807 } 28808 } 28809 } );*/ 28810 } 28811 }, { 28812 key: 'onScrollStickyElement', 28813 value: function onScrollStickyElement() { 28814 jQuery(window).on('load resize', function () { 28815 var sticky_section = jQuery('.sticky-custom-report-buttons'); 28816 if (sticky_section.length === 0) { 28817 return; 28818 } 28819 var sticky = jQuery('.custom-reports-content').offset().top; 28820 jQuery(window).on('scroll', function () { 28821 if (window.pageYOffset > sticky) { 28822 jQuery('.dt-buttons').appendTo('.sticky-custom-report-buttons'); 28823 sticky_section.addClass('sticky'); 28824 } else { 28825 jQuery('.dt-buttons').appendTo('.custom-report-buttons'); 28826 sticky_section.removeClass('sticky'); 28827 } 28828 }); 28829 }); 28830 } 28831 }, { 28832 key: 'toggleHiddenRow', 28833 value: function toggleHiddenRow(container, target, selector) { 28834 jQuery(document).on('click', selector, function (event) { 28835 var $self = jQuery(this); 28836 var $parent = $self.parents('.row_data'); 28837 var $target = $parent.next(); 28838 $target.toggleClass('collapse'); 28839 $self.toggleClass('active'); 28840 $parent.toggleClass('expanded'); 28841 }); 28842 } 28843 }, { 28844 key: 'showBulkExportModal', 28845 value: function showBulkExportModal(source, target) { 28846 jQuery(document).on('click', source, function () { 28847 jQuery(target).trigger('click'); 28848 }); 28849 } 28850 }]); 28851 28852 return reportingDashboard; 28853}(); 28854 28855exports.default = reportingDashboard; 28856 28857/***/ }), 28858/* 10 */ 28859/***/ (function(module, exports, __webpack_require__) { 28860 28861"use strict"; 28862 28863 28864Object.defineProperty(exports, "__esModule", { 28865 value: true 28866}); 28867 28868var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // cspell:ignore toggleon . 28869/* globals qre_export_obj: false, URLSearchParams: false */ 28870 28871 28872var _jsDatepicker = __webpack_require__(3); 28873 28874var _jsDatepicker2 = _interopRequireDefault(_jsDatepicker); 28875 28876function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28877 28878function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 28879 28880/** 28881 * This class does all the processing related to filtering results. 28882 */ 28883var resultFilters = function () { 28884 function resultFilters() { 28885 _classCallCheck(this, resultFilters); 28886 28887 this.search_string = ''; 28888 this.selected_result = { 28889 id: 0, 28890 type: '', 28891 text: '' 28892 }; 28893 } 28894 /** 28895 * This method is used to toggle between period and date range filters 28896 * @param {string} container Container for the input field. 28897 * @param {string} selector Hidden checkbox for the Toggle button. 28898 */ 28899 28900 28901 _createClass(resultFilters, [{ 28902 key: 'toggle', 28903 value: function toggle(container, selector) { 28904 jQuery(container).on('change', selector, function () { 28905 jQuery(this).parents('.date-filter').toggleClass('toggleon'); 28906 jQuery(this).parents('.toggle').find('.option').toggleClass('active'); 28907 }); 28908 } 28909 /** 28910 * This method is used to initialize both the date selectors and establish a date range relation between them. 28911 * @param {string} selectors Selectors for both the date fields. 28912 */ 28913 28914 }, { 28915 key: 'datepicker_init', 28916 value: function datepicker_init(selectors) { 28917 var args = { 28918 id: 1, 28919 formatter: function formatter(input, date, instance) { 28920 instance = instance; 28921 var value = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); 28922 input.value = value; // => 'F j, Y' 28923 } 28924 }; 28925 var args_clone; 28926 for (var i = 0; i <= selectors.length - 1; i++) { 28927 if (jQuery(selectors[i]).length === 0) { 28928 continue; 28929 } 28930 args_clone = Object.assign({}, args); 28931 if (jQuery(selectors[i]).val().length !== 0) { 28932 args_clone.dateSelected = new Date(jQuery(selectors[i]).val()); 28933 } 28934 (0, _jsDatepicker2.default)(selectors[i], args_clone); 28935 } 28936 } 28937 /** 28938 * This method is used to perform the live search operation for the keyword based on quiz title or user. 28939 * @param {string}
28939 selector Selector for search field. 28940 */ 28941 28942 }, { 28943 key: 'search', 28944 value: function search(selector) { 28945 var instance = this; 28946 /* On typing */ 28947 jQuery(selector).on('keyup', this.delay(function (event) { 28948 event.stopPropagation(); 28949 var query = jQuery(this).val(); 28950 var search_field = jQuery(this); 28951 if (query === instance.search_string) { 28952 return; 28953 } 28954 instance.search_string = query; 28955 if (search_field.next().hasClass('search_results') || search_field.next().hasClass('reset_search')) { 28956 search_field.next().remove(); 28957 } 28958 if (instance.search_string.length < 3) { 28959 return; 28960 } 28961 jQuery(selector).addClass('searching'); 28962 jQuery.ajax({ 28963 type: 'POST', 28964 url: qre_export_obj.ajax_url, 28965 timeout: 10000, 28966 retry_count: 0, 28967 retry_limit: 1, 28968 data: { 28969 action: 'qre_live_search', 28970 security: qre_export_obj.search_results_nonce, 28971 query: instance.search_string 28972 }, 28973 success: function success(result) { 28974 jQuery(selector).removeClass('searching'); 28975 if (!result.success) { 28976 search_field.after('<span class="search_results">' + result.data.message + '</span>'); 28977 return; 28978 } 28979 search_field.parent().append('<ul class="search_results"></ul>'); 28980 for (var i = 0; i < result.data.length; i++) { 28981 search_field.parent().find('ul').append('<li class="' + result.data[i].icon + '" data-id="' + result.data[i].ID + '" data-type="' + result.data[i].type + '">' + result.data[i].title + '</li>'); 28982 } 28983 }, 28984 error: function error(xhr, status, error_thrown) { 28985 if (status === 'timeout') { 28986 this.retry_count++; 28987 if (this.retry_count <= this.retry_limit) { 28988 console.log('Retrying'); 28989 jQuery.ajax(this); 28990 return; 28991 } else { 28992 console.error('request timed out'); 28993 jQuery(selector).removeClass('searching'); 28994 search_field.after('<span class="search_results">' + qre_export_obj.timeout_message + '</span>'); 28995 } 28996 } else { 28997 console.log(error_thrown); 28998 jQuery(selector).removeClass('searching'); 28999 search_field.after('<span class="search_results">' + error_thrown + '</span>'); 29000 } 29001 } 29002 }); 29003 }, 500)); 29004 } 29005 /** 29006 * This method is used to delay a callback by sometime to prevent flooding of events. 29007 * (like keyup or mouse scroll which are frequent events.) 29008 * @param {Function} fn Callback to delay. 29009 * @param {number} ms Time in milliseconds. 29010 * @return {Function} Same function delayed by required time. 29011 */ 29012 29013 }, { 29014 key: 'delay', 29015 value: function delay(fn, ms) { 29016 var timer = 0; 29017 return function () { 29018 clearTimeout(timer); 29019 29020 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 29021 args[_key] = arguments[_key]; 29022 } 29023 29024 timer = setTimeout(fn.bind.apply(fn, [this].concat(args)), ms || 0); 29025 }; 29026 } 29027 29028 /** 29029 * This method is used to select a result for further processing. 29030 * 29031 * @param {string} search_input Selector for search field. 29032 * @param {string} type_selector Selector for hidden input which stores query type. 29033 * @param {string} id_selector Selector for hidden input which stores query object id. 29034 */ 29035 29036 }, { 29037 key: 'select_result', 29038 value: function select_result(search_input, type_selector, id_selector) { 29039 var instance = this; 29040 jQuery(document).on('click', '.search-reports ul.search_results li', function () { 29041 var query = jQuery(this); 29042 if (instance.selected_result.id === query.attr('data-id')) { 29043 return; 29044 } 29045 instance.selected_result.id = query.attr('data-id'); 29046 instance.selected_result.type = query.attr('data-type'); 29047 instance.selected_result.text = instance.search_string = query.text(); 29048 jQuery(search_input).val(instance.selected_result.text); 29049 jQuery(type_selector).val(instance.selected_result.type); 29050 jQuery(id_selector).val(instance.selected_result.id); 29051 if (jQuery(search_input).next().hasClass('search_results')) { 29052 jQuery(search_input).next().remove(); 29053 } 29054 jQuery(search_input).after('<span class="reset_search"></span>'); 29055 }); 29056 } 29057 29058 /** 29059 * This method is used to select a result for further processing. 29060 * 29061 * @param {string}
29061 search_input Selector for search field. 29062 * @param {string} type_selector Selector for hidden input which stores query type. 29063 * @param {string} id_selector Selector for hidden input which stores query object id. 29064 */ 29065 29066 }, { 29067 key: 'reset_search', 29068 value: function reset_search(search_input, type_selector, id_selector) { 29069 var instance = this; 29070 jQuery('body').on('click', '.reset_search', function () { 29071 jQuery(search_input).val(''); 29072 jQuery(type_selector).val(''); 29073 jQuery(id_selector).val(0); 29074 instance.search_string = ''; 29075 instance.selected_result = { 29076 id: 0, 29077 type: '', 29078 text: '' 29079 }; 29080 jQuery(this).remove(); 29081 }); 29082 } 29083 29084 /** 29085 * This method is used to change number of entries shown per page. 29086 * @param string pagination_form Pagination Form Selector. 29087 * @param string limit_selector Limit Dropdown Selector. 29088 */ 29089 29090 }, { 29091 key: 'change_entry_count', 29092 value: function change_entry_count(pagination_form, limit_selector) { 29093 var self = this; 29094 jQuery(limit_selector).on('change', function () { 29095 if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) { 29096 jQuery(pagination_form).submit(); 29097 return; 29098 } 29099 self.add_filters_to_pagination(pagination_form); 29100 jQuery(pagination_form).submit(); 29101 }); 29102 } 29103 29104 /** 29105 * This method is used to control pagination inputs. 29106 * @param string pagination_form Pagination form Selector 29107 * @param string page_number_selector Page Number Input Selector 29108 * @param string previous_page_btn Previous page button Selector 29109 * @param string next_page_button Next page button Selector 29110 */ 29111 29112 }, { 29113 key: 'change_page_number', 29114 value: function change_page_number(pagination_form, page_number_selector, previous_page_btn, next_page_button) { 29115 var self = this; 29116 jQuery(page_number_selector).on('change', function () { 29117 var page_number = parseInt(jQuery(this).val()); 29118 var max_page_number = parseInt(jQuery(this).attr('data-max')); 29119 if (isNaN(page_number)) { 29120 return false; 29121 } 29122 if (page_number > max_page_number) { 29123 return false; 29124 } 29125 jQuery(pagination_form).find('input[name=pageno]').val(page_number); 29126 if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) { 29127 jQuery(pagination_form).submit(); 29128 return; 29129 } 29130 self.add_filters_to_pagination(pagination_form); 29131 jQuery(pagination_form).submit(); 29132 }); 29133 jQuery(next_page_button).on('click', function () { 29134 var page_number = parseInt(jQuery(page_number_selector).val()); 29135 var max_page_number = parseInt(jQuery(page_number_selector).attr('data-max')); 29136 if (page_number === max_page_number) { 29137 jQuery(this).attr('disabled', 'disabled'); 29138 return false; 29139 } 29140 jQuery(pagination_form).find('input[name=pageno]').val(page_number + 1); 29141 if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) { 29142 jQuery(pagination_form).submit(); 29143 return; 29144 } 29145 self.add_filters_to_pagination(pagination_form); 29146 jQuery(pagination_form).submit(); 29147 }); 29148 jQuery(previous_page_btn).on('click', function () { 29149 var page_number = parseInt(jQuery(page_number_selector).val()); 29150 if (page_number === 1) { 29151 jQuery(this).attr('disabled', 'disabled'); 29152 return false; 29153 } 29154 jQuery(pagination_form).find('input[name=pageno]').val(page_number - 1); 29155 if (!self.check_query_params('qre_dashboard_filter_nonce') && !self.check_query_params('screen')) { 29156 jQuery(pagination_form).submit(); 29157 return; 29158 } 29159 self.add_filters_to_pagination(pagination_form); 29160 jQuery(pagination_form).submit(); 29161 }); 29162 } 29163 29164 /** 29165 * This method is used to check if a query param exists. 29166 * @param string field Query Param 29167 */ 29168 29169 }, { 29170 key: 'check_query_params', 29171 value: function check_query_params(field) { 29172 var url = window.location.href; 29173 if (url.indexOf('?' + field + '=') !== -1) { 29174 return true; 29175 } else if (url.indexOf('&' + field + '=') !== -1) { 29176 return true; 29177 } 29178 return false; 29179 } 29180 29181 /** 29182 * Add user selected filters to pagination. 29183 * @param string pagination_form Form Selectors. 29184 */ 29185 29186 }, { 29187 key: 'add_filters_to_pagination', 29188 value: function add_filters_to_pagination(pagination_form) { 29189 var url_params = new URLSearchParams(window.location.search); 29190 var filters = url_params.keys(); 29191 var _iteratorNormalCompletion = true; 29192 var _didIteratorError = false;
29193 var _iteratorError = undefined; 29194 29195 try { 29196 for (var _iterator = filters[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 29197 var param = _step.value; 29198 29199 if (-1 !== jQuery.inArray(param, ['limit', 'pageno'])) { 29200 continue; 29201 } 29202 var input = jQuery('<input>').attr('type', 'hidden').attr('name', param).val(jQuery('[name=' + param + ']').val()); 29203 jQuery(pagination_form).append(input); 29204 } 29205 } catch (err) { 29206 _didIteratorError = true; 29207 _iteratorError = err; 29208 } finally { 29209 try { 29210 if (!_iteratorNormalCompletion && _iterator.return) { 29211 _iterator.return(); 29212 } 29213 } finally { 29214 if (_didIteratorError) { 29215 throw _iteratorError; 29216 } 29217 } 29218 } 29219 } 29220 }]); 29221 29222 return resultFilters; 29223}(); 29224 29225exports.default = resultFilters; 29226 29227/***/ }), 29228/* 11 */ 29229/***/ (function(module, exports, __webpack_require__) { 29230 29231"use strict"; 29232 29233 29234Object.defineProperty(exports, "__esModule", { 29235 value: true 29236}); 29237 29238var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** 29239 * This class iz used to load quiz data and other UI events related to the shortcode. 29240 */ 29241/* globals qre_export_obj: false */ 29242 29243 29244var _jsDatepicker = __webpack_require__(3); 29245 29246var _jsDatepicker2 = _interopRequireDefault(_jsDatepicker); 29247 29248function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 29249 29250function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 29251 29252/** 29253 * This class does all the processing related to filtering results. 29254 */ 29255var customReports = function () { 29256 function customReports() { 29257 _classCallCheck(this, customReports); 29258 } 29259 29260 _createClass(customReports, [{ 29261 key: 'save_config', 29262 value: function save_config(container, button) { 29263 jQuery(button).on('click', function () { 29264 var form_data = {}; 29265 29266 jQuery(container).find('input[type=checkbox]').each(function (ind, el) { 29267 if (jQuery(el).is(':checked')) { 29268 form_data[jQuery(el).attr('name')] = jQuery(el).val(); 29269 // form_data.append( jQuery( el ).attr( 'name' ), jQuery( el ).val() ); 29270 } 29271 }); 29272 jQuery(container).find('select, input[type=text]').each(function (ind, el) { 29273 form_data[jQuery(el).attr('name')] = jQuery(el).val(); 29274 }); 29275 29276 jQuery(button).attr('disabled', 'disabled'); 29277 jQuery.ajax({ 29278 type: 'POST', 29279 url: qre_export_obj.ajax_url, 29280 timeout: 10000, 29281 retry_count: 0, 29282 retry_limit: 1, 29283 data: { 29284 action: 'qre_save_filters', 29285 security: qre_export_obj.custom_reports_nonce, 29286 fields: form_data 29287 }, 29288 success: function success(result) { 29289 jQuery(button).removeAttr('disabled'); 29290 jQuery(document).trigger('custom_reports_config_set'); 29291 result = result; 29292 }, 29293 error: function error(xhr, status, error_thrown) { 29294 if (status === 'timeout') { 29295 this.retry_count++; 29296 if (this.retry_count <= this.retry_limit) { 29297 console.log('Retrying'); 29298 jQuery.ajax(this); 29299 return; 29300 } else { 29301 console.error('request timed out'); 29302 jQuery(button).removeAttr('disabled'); 29303 jQuery(document).trigger('custom_reports_config_set'); 29304 } 29305 } else { 29306 console.log(error_thrown); 29307 jQuery(button).removeAttr('disabled'); 29308 jQuery(document).trigger('custom_reports_config_set'); 29309 } 29310 } 29311 }); 29312 }); 29313 } 29314 }, { 29315 key: 'toggle_filter_group', 29316 value: function toggle_filter_group(container, button) { 29317 jQuery(container).on('click', button, function () { 29318 var $this = jQuery(this); 29319 var $all = jQuery(button); 29320 var open = false;
29321 if ($this.hasClass('expanded')) { 29322 open = true; 29323 } 29324 $all.removeClass('expanded'); 29325 $all.parents('.section').find('.section-body').removeClass('expanded'); 29326 if (!open) { 29327 $this.toggleClass('expanded'); 29328 $this.parents('.section').find('.section-body').toggleClass('expanded'); 29329 } 29330 }); 29331 } 29332 }, { 29333 key: 'fetch_data', 29334 value: function fetch_data(button, save_button) { 29335 jQuery(button).on('click', function () { 29336 jQuery('.custom-reports-content').addClass('loading'); 29337 // jQuery( button ).css( 'visibility', 'hidden' ); 29338 jQuery(save_button).trigger('click'); 29339 setTimeout(function () { 29340 jQuery(button).text(qre_export_obj.preview_report_btn_text); 29341 }, 1000); 29342 }); 29343 jQuery(document).on('custom_reports_config_set', function () { 29344 jQuery.ajax({ 29345 type: 'GET', 29346 url: window.location.href, 29347 timeout: 60000, 29348 retry_count: 0, 29349 retry_limit: 1, 29350 data: { 29351 action: 'qre_get_filters', 29352 security: qre_export_obj.fetch_custom_reports 29353 }, 29354 success: function success(result) { 29355 // if ( ! result.success ) { 29356 // jQuery('.custom-reports-content').removeClass('loading'); 29357 // jQuery( button ).css( 'visibility', 'visible' ); 29358 // return; 29359 // } 29360 //jQuery('.custom-reports-container').html( jQuery( result ).find( '.custom-reports-container' ).html() ); 29361 // jQuery(document).trigger('custom_report_created', [compiled_data] ); 29362 // jQuery('.custom-reports-container').html( jQuery( result ).find( '.custom-reports-container' ).html() ); 29363 jQuery('.custom-reports-content').removeClass('loading'); 29364 window.location.replace(qre_export_obj.first_custom_url); 29365 }, 29366 error: function error(xhr, status, error_thrown) { 29367 if (status === 'timeout') { 29368 this.retry_count++; 29369 if (this.retry_count <= this.retry_limit) { 29370 console.log('Retrying'); 29371 jQuery.ajax(this); 29372 return; 29373 } else { 29374 console.error('request timed out'); 29375 // jQuery( button ).removeAttr( 'disabled' ); 29376 jQuery('.custom-reports-content').removeClass('loading'); 29377 } 29378 } else { 29379 console.log(error_thrown); 29380 // jQuery( button ).removeAttr( 'disabled' ); 29381 jQuery('.custom-reports-content').removeClass('loading'); 29382 } 29383 } 29384 }); 29385 }); 29386 } 29387 /** 29388 * This method is used to initialize both the date selectors and establish a date range relation between them. 29389 * @param {string} selectors Selectors for both the date fields. 29390 */ 29391 29392 }, { 29393 key: 'datepicker_init', 29394 value: function datepicker_init(selectors) { 29395 var did = Math.floor(Math.random() * Math.floor(100)); 29396 var args = { 29397 id: did, 29398 formatter: function formatter(input, date, instance) { 29399 instance = instance; 29400 var value = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); 29401 input.value = value; // => 'F j, Y' 29402 } 29403 }; 29404 var args_clone; 29405 for (var counter_i = 0; counter_i <= selectors.length - 1; counter_i++) { 29406 if (jQuery(selectors[counter_i]).length === 0) { 29407 continue; 29408 } 29409 args_clone = Object.assign({}, args); 29410 if (jQuery(selectors[counter_i]).val().length !== 0) { 29411 args_clone.dateSelected = new Date(jQuery(selectors[counter_i]).val()); 29412 } 29413 (0, _jsDatepicker2.default)(selectors[counter_i], args_clone); 29414 } 29415 } 29416 }]); 29417 29418 return customReports; 29419}(); 29420 29421exports.default = customReports; 29422 29423/***/ }), 29424/* 12 */ 29425/***/ (function(module, exports, __webpack_require__) { 29426 29427var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 29428 * HTML5 export buttons for Buttons and DataTables. 29429 * 2016 SpryMedia Ltd - datatables.net/license 29430 * 29431 * FileSaver.js (1.3.3) - MIT license 29432 * Copyright © 2016 Eli Grey - http://eligrey.com 29433 */ 29434 29435(function( factory ){ 29436 if ( true ) { 29437 // AMD 29438 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1), __webpack_require__(4)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) { 29439 return factory( $, window, document ); 29440 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 29441 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 29442 } 29443 else {} 29444}(function( $, window, document, jszip, pdfmake, undefined ) { 29445'use strict'; 29446var DataTable = $.fn.dataTable; 29447 29448// Allow the constructor to pass in JSZip and PDFMake from external requires. 29449// Otherwise, use globally defined variables, if they are available. 29450function _jsZip () { 29451 return jszip || window.JSZip; 29452} 29453function _pdfMake () { 29454 return pdfmake || window.pdfMake; 29455} 29456 29457DataTable.Buttons.pdfMake = function (_) { 29458 if ( ! _ ) { 29459 return _pdfMake(); 29460 } 29461 pdfmake = _; 29462} 29463 29464DataTable.Buttons.jszip = function (_) { 29465 if ( ! _ ) { 29466 return _jsZip(); 29467 } 29468 jszip = _; 29469} 29470 29471 29472/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 29473 * FileSaver.js dependency 29474 */ 29475 29476/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ 29477 29478var _saveAs = (function(view) { 29479 "use strict"; 29480 // IE <10 is explicitly unsupported 29481 if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { 29482 return; 29483 } 29484 var 29485 doc = view.document 29486 // only get URL when necessary in case Blob.js hasn't overridden it yet 29487 , get_URL = function() { 29488 return view.URL || view.webkitURL || view; 29489 } 29490 , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") 29491 , can_use_save_link = "download" in save_link 29492 , click = function(node) { 29493 var event = new MouseEvent("click"); 29494 node.dispatchEvent(event); 29495 } 29496 , is_safari = /constructor/i.test(view.HTMLElement) || view.safari 29497 , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) 29498 , throw_outside = function(ex) { 29499 (view.setImmediate || view.setTimeout)(function() { 29500 throw ex; 29501 }, 0); 29502 } 29503 , force_saveable_type = "application/octet-stream" 29504 // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to 29505 , arbitrary_revoke_timeout = 1000 * 40 // in ms 29506 , revoke = function(file) { 29507 var revoker = function() { 29508 if (typeof file === "string") { // file is an object URL 29509 get_URL().revokeObjectURL(file); 29510 } else { // file is a File 29511 file.remove(); 29512 } 29513 }; 29514 setTimeout(revoker, arbitrary_revoke_timeout); 29515 } 29516 , dispatch = function(filesaver, event_types, event) { 29517 event_types = [].concat(event_types); 29518 var i = event_types.length; 29519 while (i--) { 29520 var listener = filesaver["on" + event_types[i]]; 29521 if (typeof listener === "function") { 29522 try { 29523 listener.call(filesaver, event || filesaver); 29524 } catch (ex) { 29525 throw_outside(ex); 29526 } 29527 } 29528 } 29529 } 29530 , auto_bom = function(blob) { 29531 // prepend BOM for UTF-8 XML and text/* types (including HTML) 29532 // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF 29533 if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { 29534 return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); 29535 } 29536 return blob; 29537 } 29538 , FileSaver = function(blob, name, no_auto_bom) { 29539 if (!no_auto_bom) { 29540 blob = auto_bom(blob); 29541 } 29542 // First try a.download, then web filesystem, then object URLs 29543 var 29544 filesaver = this 29545 , type = blob.type 29546 , force = type === force_saveable_type 29547 , object_url 29548 , dispatch_all = function() { 29549 dispatch(filesaver, "writestart progress write writeend".split(" ")); 29550 } 29551 // on any filesys errors revert to saving with object URLs 29552 , fs_error = function() { 29553 if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { 29554 // Safari doesn't allow downloading of blob urls 29555 var reader = new FileReader(); 29556 reader.onloadend = function() { 29557 var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); 29558 var popup = view.open(url, '_blank'); 29559 if(!popup) view.location.href = url; 29560 url=undefined; // release reference before dispatching 29561 filesaver.readyState = filesaver.DONE; 29562 dispatch_all(); 29563 };
29564 reader.readAsDataURL(blob); 29565 filesaver.readyState = filesaver.INIT; 29566 return; 29567 } 29568 // don't create more object URLs than needed 29569 if (!object_url) { 29570 object_url = get_URL().createObjectURL(blob); 29571 } 29572 if (force) { 29573 view.location.href = object_url; 29574 } else { 29575 var opened = view.open(object_url, "_blank"); 29576 if (!opened) { 29577 // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html 29578 view.location.href = object_url; 29579 } 29580 } 29581 filesaver.readyState = filesaver.DONE; 29582 dispatch_all(); 29583 revoke(object_url); 29584 } 29585 ; 29586 filesaver.readyState = filesaver.INIT; 29587 29588 if (can_use_save_link) { 29589 object_url = get_URL().createObjectURL(blob); 29590 setTimeout(function() { 29591 save_link.href = object_url; 29592 save_link.download = name; 29593 click(save_link); 29594 dispatch_all(); 29595 revoke(object_url); 29596 filesaver.readyState = filesaver.DONE; 29597 }); 29598 return; 29599 } 29600 29601 fs_error(); 29602 } 29603 , FS_proto = FileSaver.prototype 29604 , saveAs = function(blob, name, no_auto_bom) { 29605 return new FileSaver(blob, name || blob.name || "download", no_auto_bom); 29606 } 29607 ; 29608 // IE 10+ (native saveAs) 29609 if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { 29610 return function(blob, name, no_auto_bom) { 29611 name = name || blob.name || "download"; 29612 29613 if (!no_auto_bom) { 29614 blob = auto_bom(blob); 29615 } 29616 return navigator.msSaveOrOpenBlob(blob, name); 29617 }; 29618 } 29619 29620 FS_proto.abort = function(){}; 29621 FS_proto.readyState = FS_proto.INIT = 0; 29622 FS_proto.WRITING = 1; 29623 FS_proto.DONE = 2; 29624 29625 FS_proto.error = 29626 FS_proto.onwritestart = 29627 FS_proto.onprogress = 29628 FS_proto.onwrite = 29629 FS_proto.onabort = 29630 FS_proto.onerror = 29631 FS_proto.onwriteend = 29632 null; 29633 29634 return saveAs; 29635}( 29636 typeof self !== "undefined" && self 29637 || typeof window !== "undefined" && window 29638 || this.content 29639)); 29640 29641 29642// Expose file saver on the DataTables API. Can't attach to `DataTables.Buttons` 29643// since this file can be loaded before Button's core! 29644DataTable.fileSave = _saveAs; 29645 29646 29647/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 29648 * Local (private) functions 29649 */ 29650 29651/** 29652 * Get the sheet name for Excel exports. 29653 * 29654 * @param {object} config Button configuration 29655 */ 29656var _sheetname = function ( config ) 29657{ 29658 var sheetName = 'Sheet1'; 29659 29660 if ( config.sheetName ) { 29661 sheetName = config.sheetName.replace(/[\[\]\*\/\\\?\:]/g, ''); 29662 } 29663 29664 return sheetName; 29665}; 29666 29667/** 29668 * Get the newline character(s) 29669 * 29670 * @param {object} config Button configuration 29671 * @return {string} Newline character 29672 */ 29673var _newLine = function ( config ) 29674{ 29675 return config.newline ? 29676 config.newline : 29677 navigator.userAgent.match(/Windows/) ? 29678 '\r\n' : 29679 '\n'; 29680}; 29681 29682/** 29683 * Combine the data from the `buttons.exportData` method into a string that 29684 * will be used in the export file. 29685 * 29686 * @param {DataTable.Api} dt DataTables API instance 29687 * @param {object} config Button configuration 29688 * @return {object} The data to export 29689 */ 29690var _exportData = function ( dt, config ) 29691{ 29692 var newLine = _newLine( config ); 29693 var data = dt.buttons.exportData( config.exportOptions ); 29694 var boundary = config.fieldBoundary; 29695 var separator = config.fieldSeparator; 29696 var reBoundary = new RegExp( boundary, 'g' ); 29697 var escapeChar = config.escapeChar !== undefined ? 29698 config.escapeChar : 29699 '\\'; 29700 var join = function ( a ) { 29701 var s = ''; 29702 29703 // If there is a field boundary, then we might need to escape it in 29704 // the source data 29705 for ( var i=0, ien=a.length ; i<ien ; i++ ) { 29706 if ( i > 0 ) { 29707 s += separator; 29708 } 29709 29710 s += boundary ? 29711 boundary + ('' + a[i]).replace( reBoundary, escapeChar+boundary ) + boundary : 29712 a[i]; 29713 } 29714 29715 return s; 29716 }; 29717 29718 var header = config.header ? join( data.header )+newLine : ''; 29719 var footer = config.footer && data.footer ? newLine+join( data.footer ) : ''; 29720 var body = []; 29721 29722 for ( var i=0, ien=data.body.length ; i<ien ; i++ ) { 29723 body.push( join( data.body[i] ) ); 29724 } 29725 29726 return { 29727 str: header + body.join( newLine ) + footer, 29728 rows: body.length 29729 }; 29730}; 29731 29732/** 29733 * Older versions of Safari (prior to tech preview 18) don't support the 29734 * download option required. 29735 * 29736 * @return {Boolean} `true` if old Safari 29737 */ 29738var _isDuffSafari = function () 29739{ 29740 var safari = navigator.userAgent.indexOf('Safari') !== -1 && 29741 navigator.userAgent.indexOf('Chrome') === -1 && 29742 navigator.userAgent.indexOf('Opera') === -1; 29743 29744 if ( ! safari ) { 29745 return false;
29746 } 29747 29748 var version = navigator.userAgent.match( /AppleWebKit\/(\d+\.\d+)/ ); 29749 if ( version && version.length > 1 && version[1]*1 < 603.1 ) { 29750 return true; 29751 } 29752 29753 return false; 29754}; 29755 29756/** 29757 * Convert from numeric position to letter for column names in Excel 29758 * @param {int} n Column number 29759 * @return {string} Column letter(s) name 29760 */ 29761function createCellPos( n ){ 29762 var ordA = 'A'.charCodeAt(0); 29763 var ordZ = 'Z'.charCodeAt(0); 29764 var len = ordZ - ordA + 1; 29765 var s = ""; 29766 29767 while( n >= 0 ) { 29768 s = String.fromCharCode(n % len + ordA) + s; 29769 n = Math.floor(n / len) - 1; 29770 } 29771 29772 return s; 29773} 29774 29775try { 29776 var _serialiser = new XMLSerializer(); 29777 var _ieExcel; 29778} 29779catch (t) {} 29780 29781/** 29782 * Recursively add XML files from an object's structure to a ZIP file. This 29783 * allows the XSLX file to be easily defined with an object's structure matching 29784 * the files structure. 29785 * 29786 * @param {JSZip} zip ZIP package 29787 * @param {object} obj Object to add (recursive) 29788 */ 29789function _addToZip( zip, obj ) { 29790 if ( _ieExcel === undefined ) { 29791 // Detect if we are dealing with IE's _awful_ serialiser by seeing if it 29792 // drop attributes 29793 _ieExcel = _serialiser 29794 .serializeToString( 29795 ( new window.DOMParser() ).parseFromString( excelStrings['xl/worksheets/sheet1.xml'], 'text/xml' ) 29796 ) 29797 .indexOf( 'xmlns:r' ) === -1; 29798 } 29799 29800 $.each( obj, function ( name, val ) { 29801 if ( $.isPlainObject( val ) ) { 29802 var newDir = zip.folder( name ); 29803 _addToZip( newDir, val ); 29804 } 29805 else { 29806 if ( _ieExcel ) { 29807 // IE's XML serialiser will drop some name space attributes from 29808 // from the root node, so we need to save them. Do this by 29809 // replacing the namespace nodes with a regular attribute that 29810 // we convert back when serialised. Edge does not have this 29811 // issue 29812 var worksheet = val.childNodes[0]; 29813 var i, ien; 29814 var attrs = []; 29815 29816 for ( i=worksheet.attributes.length-1 ; i>=0 ; i-- ) { 29817 var attrName = worksheet.attributes[i].nodeName; 29818 var attrValue = worksheet.attributes[i].nodeValue; 29819 29820 if ( attrName.indexOf( ':' ) !== -1 ) { 29821 attrs.push( { name: attrName, value: attrValue } ); 29822 29823 worksheet.removeAttribute( attrName ); 29824 } 29825 } 29826 29827 for ( i=0, ien=attrs.length ; i<ien ; i++ ) { 29828 var attr = val.createAttribute( attrs[i].name.replace( ':', '_dt_b_namespace_token_' ) ); 29829 attr.value = attrs[i].value; 29830 worksheet.setAttributeNode( attr ); 29831 } 29832 } 29833 29834 var str = _serialiser.serializeToString(val); 29835 29836 // Fix IE's XML 29837 if ( _ieExcel ) { 29838 // IE doesn't include the XML declaration 29839 if ( str.indexOf( '<?xml' ) === -1 ) { 29840 str = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+str; 29841 } 29842 29843 // Return namespace attributes to being as such 29844 str = str.replace( /_dt_b_namespace_token_/g, ':' ); 29845 29846 // Remove testing name space that IE puts into the space preserve attr 29847 str = str.replace( /xmlns:NS[\d]+="" NS[\d]+:/g, '' ); 29848 } 29849 29850 // Safari, IE and Edge will put empty name space attributes onto 29851 // various elements making them useless. This strips them out 29852 str = str.replace( /<([^<>]*?) xmlns=""([^<>]*?)>/g, '<$1 $2>' ); 29853 29854 zip.file( name, str ); 29855 } 29856 } ); 29857} 29858 29859/** 29860 * Create an XML node and add any children, attributes, etc without needing to 29861 * be verbose in the DOM. 29862 * 29863 * @param {object} doc XML document 29864 * @param {string} nodeName Node name 29865 * @param {object} opts Options - can be `attr` (attributes), `children` 29866 * (child nodes) and `text` (text content) 29867 * @return {node} Created node 29868 */ 29869function _createNode( doc, nodeName, opts ) { 29870 var tempNode = doc.createElement( nodeName ); 29871 29872 if ( opts ) { 29873 if ( opts.attr ) { 29874 $(tempNode).attr( opts.attr ); 29875 } 29876 29877 if ( opts.children ) { 29878 $.each( opts.children, function ( key, value ) { 29879 tempNode.appendChild( value ); 29880 } ); 29881 } 29882 29883 if ( opts.text !== null && opts.text !== undefined ) { 29884 tempNode.appendChild( doc.createTextNode( opts.text ) ); 29885 } 29886 } 29887 29888 return tempNode; 29889} 29890 29891/** 29892 * Get the width for an Excel column based on the contents of that column 29893 * @param {object} data Data for export 29894 * @param {int} col Column index 29895 * @return {int} Column width 29896 */ 29897function _excelColWidth( data, col ) { 29898 var max = data.header[col].length; 29899 var len, lineSplit, str; 29900 29901 if ( data.footer && data.footer[col].length > max ) { 29902 max = data.footer[col].length; 29903 } 29904 29905 for ( var i=0, ien=data.body.length ; i<ien ; i++ ) { 29906 var point = data.body[i][col]; 29907 str = point !== null && point !== undefined ? 29908 point.toString() : 29909 ''; 29910 29911 // If there is a newline character, workout the width of the column 29912 // based on the longest line in the string 29913 if ( str.indexOf('\n') !== -1 ) { 29914 lineSplit = str.split('\n'); 29915 lineSplit.sort( function (a, b) { 29916 return b.length - a.length; 29917 } ); 29918 29919 len = lineSplit[0].length; 29920 } 29921 else { 29922 len = str.length; 29923 } 29924 29925 if ( len > max ) { 29926 max = len; 29927 } 29928 29929 // Max width rather than having potentially massive column widths 29930 if ( max > 40 ) { 29931 return 54; // 40 * 1.35 29932 } 29933 } 29934 29935 max *= 1.35; 29936 29937 // And a min width 29938 return max > 6 ? max : 6; 29939} 29940 29941// Excel - Pre-defined strings to build a basic XLSX file 29942var excelStrings = { 29943 "_rels/.rels": 29944 '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+ 29945 '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'+ 29946 '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>'+ 29947 '</Relationships>', 29948 29949 "xl/_rels/workbook.xml.rels": 29950 '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+ 29951 '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'+ 29952 '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>'+ 29953 '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>'+ 29954 '</Relationships>', 29955 29956 "[Content_Types].xml": 29957 '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+ 29958 '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">'+ 29959 '<Default Extension="xml" ContentType="application/xml" />'+ 29960 '<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />'+ 29961 '<Default Extension="jpeg" ContentType="image/jpeg" />'+
29962 '<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />'+ 29963 '<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />'+ 29964 '<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />'+ 29965 '</Types>', 29966 29967 "xl/workbook.xml": 29968 '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+ 29969 '<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">'+ 29970 '<fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="24816"/>'+ 29971 '<workbookPr showInkAnnotation="0" autoCompressPictures="0"/>'+ 29972 '<bookViews>'+ 29973 '<workbookView xWindow="0" yWindow="0" windowWidth="25600" windowHeight="19020" tabRatio="500"/>'+ 29974 '</bookViews>'+ 29975 '<sheets>'+ 29976 '<sheet name="Sheet1" sheetId="1" r:id="rId1"/>'+ 29977 '</sheets>'+ 29978 '<definedNames/>'+ 29979 '</workbook>', 29980 29981 "xl/worksheets/sheet1.xml": 29982 '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+ 29983 '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+ 29984 '<sheetData/>'+ 29985 '<mergeCells count="0"/>'+ 29986 '</worksheet>', 29987 29988 "xl/styles.xml": 29989 '<?xml version="1.0" encoding="UTF-8"?>'+ 29990 '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">'+ 29991 '<numFmts count="6">'+ 29992 '<numFmt numFmtId="164" formatCode="#,##0.00_-\ [$$-45C]"/>'+ 29993 '<numFmt numFmtId="165" formatCode=""£"#,##0.00"/>'+ 29994 '<numFmt numFmtId="166" formatCode="[$â¬-2]\ #,##0.00"/>'+ 29995 '<numFmt numFmtId="167" formatCode="0.0%"/>'+ 29996 '<numFmt numFmtId="168" formatCode="#,##0;(#,##0)"/>'+ 29997 '<numFmt numFmtId="169" formatCode="#,##0.00;(#,##0.00)"/>'+ 29998 '</numFmts>'+ 29999 '<fonts count="5" x14ac:knownFonts="1">'+ 30000 '<font>'+ 30001 '<sz val="11" />'+ 30002 '<name val="Calibri" />'+ 30003 '</font>'+ 30004 '<font>'+ 30005 '<sz val="11" />'+ 30006 '<name val="Calibri" />'+ 30007 '<color rgb="FFFFFFFF" />'+ 30008 '</font>'+ 30009 '<font>'+ 30010 '<sz val="11" />'+ 30011 '<name val="Calibri" />'+ 30012 '<b />'+ 30013 '</font>'+ 30014 '<font>'+ 30015 '<sz val="11" />'+ 30016 '<name val="Calibri" />'+ 30017 '<i />'+ 30018 '</font>'+ 30019 '<font>'+ 30020 '<sz val="11" />'+ 30021 '<name val="Calibri" />'+ 30022 '<u />'+ 30023 '</font>'+ 30024 '</fonts>'+ 30025 '<fills count="6">'+ 30026 '<fill>'+ 30027 '<patternFill patternType="none" />'+ 30028 '</fill>'+ 30029 '<fill>'+ // Excel appears to use this as a dotted background regardless of values but 30030 '<patternFill patternType="none" />'+ // to be valid to the schema, use a patternFill 30031 '</fill>'+ 30032 '<fill>'+ 30033 '<patternFill patternType="solid">'+ 30034 '<fgColor rgb="FFD9D9D9" />'+ 30035 '<bgColor indexed="64" />'+ 30036 '</patternFill>'+ 30037 '</fill>'+ 30038 '<fill>'+ 30039 '<patternFill patternType="solid">'+ 30040 '<fgColor rgb="FFD99795" />'+ 30041 '<bgColor indexed="64" />'+ 30042 '</patternFill>'+ 30043 '</fill>'+ 30044 '<fill>'+ 30045 '<patternFill patternType="solid">'+ 30046 '<fgColor rgb="ffc6efce" />'+ 30047 '<bgColor indexed="64" />'+ 30048 '</patternFill>'+ 30049 '</fill>'+ 30050 '<fill>'+ 30051 '<patternFill patternType="solid">'+ 30052 '<fgColor rgb="ffc6cfef" />'+ 30053 '<bgColor indexed="64" />'+ 30054 '</patternFill>'+ 30055 '</fill>'+ 30056 '</fills>'+ 30057 '<borders count="2">'+ 30058 '<border>'+ 30059 '<left />'+ 30060 '<right />'+ 30061 '<top />'+ 30062 '<bottom />'+ 30063 '<diagonal />'+ 30064 '</border>'+ 30065 '<border diagonalUp="false" diagonalDown="false">'+ 30066 '<left style="thin">'+ 30067 '<color auto="1" />'+ 30068 '</left>'+ 30069 '<right style="thin">'+ 30070 '<color auto="1" />'+ 30071 '</right>'+ 30072 '<top style="thin">'+ 30073 '<color auto="1" />'+ 30074 '</top>'+ 30075 '<bottom style="thin">'+ 30076 '<color auto="1" />'+ 30077 '</bottom>'+ 30078 '<diagonal />'+ 30079 '</border>'+ 30080 '</borders>'+ 30081 '<cellStyleXfs count="1">'+ 30082 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" />'+ 30083 '</cellStyleXfs>'+ 30084 '<cellXfs count="68">'+ 30085 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30086 '<xf numFmtId="0" fontId="1" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30087 '<xf numFmtId="0" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30088 '<xf numFmtId="0" fontId="3" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30089 '<xf numFmtId="0" fontId="4" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30090 '<xf numFmtId="0" fontId="0" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30091 '<xf numFmtId="0" fontId="1" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30092 '<xf numFmtId="0" fontId="2" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30093 '<xf numFmtId="0" fontId="3" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30094 '<xf numFmtId="0" fontId="4" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30095 '<xf numFmtId="0" fontId="0" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30096 '<xf numFmtId="0" fontId="1" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30097 '<xf numFmtId="0" fontId="2" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30098 '<xf numFmtId="0" fontId="3" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30099 '<xf numFmtId="0" fontId="4" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30100 '<xf numFmtId="0" fontId="0" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30101 '<xf numFmtId="0" fontId="1" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30102 '<xf numFmtId="0" fontId="2" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30103 '<xf numFmtId="0" fontId="3" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30104 '<xf numFmtId="0" fontId="4" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30105 '<xf numFmtId="0" fontId="0" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30106 '<xf numFmtId="0" fontId="1" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30107 '<xf numFmtId="0" fontId="2" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30108 '<xf numFmtId="0" fontId="3" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30109 '<xf numFmtId="0" fontId="4" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30110 '<xf numFmtId="0" fontId="0" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30111 '<xf numFmtId="0" fontId="1" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30112 '<xf numFmtId="0" fontId="2" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30113 '<xf numFmtId="0" fontId="3" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30114 '<xf numFmtId="0" fontId="4" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30115 '<xf numFmtId="0" fontId="0" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30116 '<xf numFmtId="0" fontId="1" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30117 '<xf numFmtId="0" fontId="2" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30118 '<xf numFmtId="0" fontId="3" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30119 '<xf numFmtId="0" fontId="4" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30120 '<xf numFmtId="0" fontId="0" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30121 '<xf numFmtId="0" fontId="1" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30122 '<xf numFmtId="0" fontId="2" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30123 '<xf numFmtId="0" fontId="3" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30124 '<xf numFmtId="0" fontId="4" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30125 '<xf numFmtId="0" fontId="0" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30126 '<xf numFmtId="0" fontId="1" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30127 '<xf numFmtId="0" fontId="2" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30128 '<xf numFmtId="0" fontId="3" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30129 '<xf numFmtId="0" fontId="4" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30130 '<xf numFmtId="0" fontId="0" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30131 '<xf numFmtId="0" fontId="1" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30132 '<xf numFmtId="0" fontId="2" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30133 '<xf numFmtId="0" fontId="3" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30134 '<xf numFmtId="0" fontId="4" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>'+ 30135 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+ 30136 '<alignment horizontal="left"/>'+ 30137 '</xf>'+ 30138 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+ 30139 '<alignment horizontal="center"/>'+ 30140 '</xf>'+ 30141 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+ 30142 '<alignment horizontal="right"/>'+ 30143 '</xf>'+ 30144 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+ 30145 '<alignment horizontal="fill"/>'+ 30146 '</xf>'+ 30147 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+ 30148 '<alignment textRotation="90"/>'+ 30149 '</xf>'+ 30150 '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">'+ 30151 '<alignment wrapText="1"/>'+ 30152 '</xf>'+ 30153 '<xf numFmtId="9" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30154 '<xf numFmtId="164" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30155 '<xf numFmtId="165" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30156 '<xf numFmtId="166" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30157 '<xf numFmtId="167" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30158 '<xf numFmtId="168" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30159 '<xf numFmtId="169" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30160 '<xf numFmtId="3" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30161 '<xf numFmtId="4" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30162 '<xf numFmtId="1" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30163 '<xf numFmtId="2" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30164 '<xf numFmtId="14" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>'+ 30165 '</cellXfs>'+ 30166 '<cellStyles count="1">'+ 30167 '<cellStyle name="Normal" xfId="0" builtinId="0" />'+ 30168 '</cellStyles>'+ 30169 '<dxfs count="0" />'+ 30170 '<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4" />'+ 30171 '</styleSheet>' 30172}; 30173// Note we could use 3 `for` loops for the styles, but when gzipped there is
30174// virtually no difference in size, since the above can be easily compressed 30175 30176// Pattern matching for special number formats. Perhaps this should be exposed 30177// via an API in future? 30178// Ref: section 3.8.30 - built in formatters in open spreadsheet 30179// https://www.ecma-international.org/news/TC45_current_work/Office%20Open%20XML%20Part%204%20-%20Markup%20Language%20Reference.pdf 30180var _excelSpecials = [ 30181 { match: /^\-?\d+\.\d%$/, style: 60, fmt: function (d) { return d/100; } }, // Precent with d.p. 30182 { match: /^\-?\d+\.?\d*%$/, style: 56, fmt: function (d) { return d/100; } }, // Percent 30183 { match: /^\-?\$[\d,]+.?\d*$/, style: 57 }, // Dollars 30184 { match: /^\-?£[\d,]+.?\d*$/, style: 58 }, // Pounds 30185 { match: /^\-?â¬[\d,]+.?\d*$/, style: 59 }, // Euros 30186 { match: /^\-?\d+$/, style: 65 }, // Numbers without thousand separators 30187 { match: /^\-?\d+\.\d{2}$/, style: 66 }, // Numbers 2 d.p. without thousands separators 30188 { match: /^\([\d,]+\)$/, style: 61, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } }, // Negative numbers indicated by brackets 30189 { match: /^\([\d,]+\.\d{2}\)$/, style: 62, fmt: function (d) { return -1 * d.replace(/[\(\)]/g, ''); } }, // Negative numbers indicated by brackets - 2d.p. 30190 { match: /^\-?[\d,]+$/, style: 63 }, // Numbers with thousand separators 30191 { match: /^\-?[\d,]+\.\d{2}$/, style: 64 }, 30192 { match: /^[\d]{4}\-[\d]{2}\-[\d]{2}$/, style: 67, fmt: function (d) {return Math.round(25569 + (Date.parse(d) / (86400 * 1000)));}} //Date yyyy-mm-dd 30193]; 30194 30195 30196 30197/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 30198 * Buttons 30199 */ 30200 30201// 30202// Copy to clipboard 30203// 30204DataTable.ext.buttons.copyHtml5 = { 30205 className: 'buttons-copy buttons-html5', 30206 30207 text: function ( dt ) { 30208 return dt.i18n( 'buttons.copy', 'Copy' ); 30209 }, 30210 30211 action: function ( e, dt, button, config ) { 30212 this.processing( true ); 30213 30214 var that = this; 30215 var exportData = _exportData( dt, config ); 30216 var info = dt.buttons.exportInfo( config ); 30217 var newline = _newLine(config); 30218 var output = exportData.str; 30219 var hiddenDiv = $('<div/>') 30220 .css( { 30221 height: 1, 30222 width: 1, 30223 overflow: 'hidden', 30224 position: 'fixed', 30225 top: 0, 30226 left: 0 30227 } ); 30228 30229 if ( info.title ) { 30230 output = info.title + newline + newline + output; 30231 } 30232 30233 if ( info.messageTop ) { 30234 output = info.messageTop + newline + newline + output; 30235 } 30236 30237 if ( info.messageBottom ) { 30238 output = output + newline + newline + info.messageBottom; 30239 } 30240 30241 if ( config.customize ) { 30242 output = config.customize( output, config, dt ); 30243 } 30244 30245 var textarea = $('<textarea readonly/>') 30246 .val( output ) 30247 .appendTo( hiddenDiv ); 30248 30249 // For browsers that support the copy execCommand, try to use it 30250 if ( document.queryCommandSupported('copy') ) { 30251 hiddenDiv.appendTo( dt.table().container() ); 30252 textarea[0].focus(); 30253 textarea[0].select(); 30254 30255 try { 30256 var successful = document.execCommand( 'copy' ); 30257 hiddenDiv.remove(); 30258 30259 if (successful) { 30260 dt.buttons.info( 30261 dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ), 30262 dt.i18n( 'buttons.copySuccess', { 30263 1: 'Copied one row to clipboard', 30264 _: 'Copied %d rows to clipboard' 30265 }, exportData.rows ), 30266 2000 30267 ); 30268 30269 this.processing( false ); 30270 return; 30271 } 30272 } 30273 catch (t) {} 30274 } 30275 30276 // Otherwise we show the text box and instruct the user to use it 30277 var message = $('<span>'+dt.i18n( 'buttons.copyKeys', 30278 'Press <i>ctrl</i> or <i>\u2318</i> + <i>C</i> to copy the table data<br>to your system clipboard.<br><br>'+ 30279 'To cancel, click this message or press escape.' )+'</span>' 30280 ) 30281 .append( hiddenDiv ); 30282 30283 dt.buttons.info( dt.i18n( 'buttons.copyTitle', 'Copy to clipboard' ), message, 0 ); 30284 30285 // Select the text so when the user activates their system clipboard 30286 // it will copy that text 30287 textarea[0].focus(); 30288 textarea[0].select(); 30289 30290 // Event to hide the message when the user is done 30291 var container = $(message).closest('.dt-button-info'); 30292 var close = function () { 30293 container.off( 'click.buttons-copy' ); 30294 $(document).off( '.buttons-copy' ); 30295 dt.buttons.info( false ); 30296 }; 30297 30298 container.on( 'click.buttons-copy', close ); 30299 $(document) 30300 .on( 'keydown.buttons-copy', function (e) { 30301 if ( e.keyCode === 27 ) { // esc 30302 close(); 30303 that.processing( false ); 30304 } 30305 } ) 30306 .on( 'copy.buttons-copy cut.buttons-copy', function () { 30307 close(); 30308 that.processing( false ); 30309 } ); 30310 }, 30311 30312 exportOptions: {}, 30313 30314 fieldSeparator: '\t', 30315 30316 fieldBoundary: '', 30317 30318 header: true, 30319
30320 footer: false, 30321 30322 title: '*', 30323 30324 messageTop: '*', 30325 30326 messageBottom: '*' 30327}; 30328 30329// 30330// CSV export 30331// 30332DataTable.ext.buttons.csvHtml5 = { 30333 bom: false, 30334 30335 className: 'buttons-csv buttons-html5', 30336 30337 available: function () { 30338 return window.FileReader !== undefined && window.Blob; 30339 }, 30340 30341 text: function ( dt ) { 30342 return dt.i18n( 'buttons.csv', 'CSV' ); 30343 }, 30344 30345 action: function ( e, dt, button, config ) { 30346 this.processing( true ); 30347 30348 // Set the text 30349 var output = _exportData( dt, config ).str; 30350 var info = dt.buttons.exportInfo(config); 30351 var charset = config.charset; 30352 30353 if ( config.customize ) { 30354 output = config.customize( output, config, dt ); 30355 } 30356 30357 if ( charset !== false ) { 30358 if ( ! charset ) { 30359 charset = document.characterSet || document.charset; 30360 } 30361 30362 if ( charset ) { 30363 charset = ';charset='+charset; 30364 } 30365 } 30366 else { 30367 charset = ''; 30368 } 30369 30370 if ( config.bom ) { 30371 output = String.fromCharCode(0xFEFF) + output; 30372 } 30373 30374 _saveAs( 30375 new Blob( [output], {type: 'text/csv'+charset} ), 30376 info.filename, 30377 true 30378 ); 30379 30380 this.processing( false ); 30381 }, 30382 30383 filename: '*', 30384 30385 extension: '.csv', 30386 30387 exportOptions: {}, 30388 30389 fieldSeparator: ',', 30390 30391 fieldBoundary: '"', 30392 30393 escapeChar: '"', 30394 30395 charset: null, 30396 30397 header: true, 30398 30399 footer: false 30400}; 30401 30402// 30403// Excel (xlsx) export 30404// 30405DataTable.ext.buttons.excelHtml5 = { 30406 className: 'buttons-excel buttons-html5', 30407 30408 available: function () { 30409 return window.FileReader !== undefined && _jsZip() !== undefined && ! _isDuffSafari() && _serialiser; 30410 }, 30411 30412 text: function ( dt ) { 30413 return dt.i18n( 'buttons.excel', 'Excel' ); 30414 }, 30415 30416 action: function ( e, dt, button, config ) { 30417 this.processing( true ); 30418 30419 var that = this; 30420 var rowPos = 0; 30421 var dataStartRow, dataEndRow; 30422 var getXml = function ( type ) { 30423 var str = excelStrings[ type ]; 30424 30425 //str = str.replace( /xmlns:/g, 'xmlns_' ).replace( /mc:/g, 'mc_' ); 30426 30427 return $.parseXML( str ); 30428 }; 30429 var rels = getXml('xl/worksheets/sheet1.xml'); 30430 var relsGet = rels.getElementsByTagName( "sheetData" )[0]; 30431 30432 var xlsx = { 30433 _rels: { 30434 ".rels": getXml('_rels/.rels') 30435 }, 30436 xl: { 30437 _rels: { 30438 "workbook.xml.rels": getXml('xl/_rels/workbook.xml.rels') 30439 }, 30440 "workbook.xml": getXml('xl/workbook.xml'), 30441 "styles.xml": getXml('xl/styles.xml'), 30442 "worksheets": { 30443 "sheet1.xml": rels 30444 } 30445 30446 }, 30447 "[Content_Types].xml": getXml('[Content_Types].xml') 30448 }; 30449 30450 var data = dt.buttons.exportData( config.exportOptions ); 30451 var currentRow, rowNode; 30452 var addRow = function ( row ) { 30453 currentRow = rowPos+1; 30454 rowNode = _createNode( rels, "row", { attr: {r:currentRow} } ); 30455 30456 for ( var i=0, ien=row.length ; i<ien ; i++ ) { 30457 // Concat both the Cell Columns as a letter and the Row of the cell. 30458 var cellId = createCellPos(i) + '' + currentRow; 30459 var cell = null; 30460 30461 // For null, undefined of blank cell, continue so it doesn't create the _createNode 30462 if ( row[i] === null || row[i] === undefined || row[i] === '' ) { 30463 if ( config.createEmptyCells === true ) { 30464 row[i] = ''; 30465 } 30466 else { 30467 continue; 30468 } 30469 } 30470 30471 var originalContent = row[i]; 30472 row[i] = typeof row[i].trim === 'function' 30473 ? row[i].trim() 30474 : row[i]; 30475 30476 // Special number formatting options 30477 for ( var j=0, jen=_excelSpecials.length ; j<jen ; j++ ) { 30478 var special = _excelSpecials[j]; 30479 30480 // TODO Need to provide the ability for the specials to say 30481 // if they are returning a string, since at the moment it is 30482 // assumed to be a number 30483 if ( row[i].match && ! row[i].match(/^0\d+/) && row[i].match( special.match ) ) { 30484 var val = row[i].replace(/[^\d\.\-]/g, ''); 30485 30486 if ( special.fmt ) { 30487 val = special.fmt( val ); 30488 } 30489 30490 cell = _createNode( rels, 'c', { 30491 attr: { 30492 r: cellId, 30493 s: special.style 30494 }, 30495 children: [ 30496 _createNode( rels, 'v', { text: val } ) 30497 ] 30498 } ); 30499 30500 break; 30501 } 30502 } 30503 30504 if ( ! cell ) { 30505 if ( typeof row[i] === 'number' || ( 30506 row[i].match && 30507 row[i].match(/^-?\d+(\.\d+)?$/) && 30508 ! row[i].match(/^0\d+/) ) 30509 ) { 30510 // Detect numbers - don't match numbers with leading zeros 30511 // or a negative anywhere but the start 30512 cell = _createNode( rels, 'c', { 30513 attr: { 30514 t: 'n', 30515 r: cellId 30516 }, 30517 children: [ 30518 _createNode( rels, 'v', { text: row[i] } ) 30519 ] 30520 } ); 30521 } 30522 else { 30523 // String output - replace non standard characters for text output 30524 var text = ! originalContent.replace ? 30525 originalContent : 30526 originalContent.replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, ''); 30527 30528 cell = _createNode( rels, 'c', { 30529 attr: { 30530 t: 'inlineStr', 30531 r: cellId 30532 }, 30533 children:{ 30534 row: _createNode( rels, 'is', { 30535 children: { 30536 row: _createNode( rels, 't', { 30537 text: text, 30538 attr: { 30539 'xml:space': 'preserve' 30540 } 30541 } ) 30542 } 30543 } ) 30544 } 30545 } ); 30546 } 30547 } 30548 30549 rowNode.appendChild( cell ); 30550 } 30551 30552 relsGet.appendChild(rowNode); 30553 rowPos++; 30554 }; 30555 30556 if ( config.customizeData ) { 30557 config.customizeData( data ); 30558 } 30559 30560 var mergeCells = function ( row, colspan ) { 30561 var mergeCells = $('mergeCells', rels); 30562 30563 mergeCells[0].appendChild( _createNode( rels, 'mergeCell', { 30564 attr: { 30565 ref: 'A'+row+':'+createCellPos(colspan)+row 30566 } 30567 } ) ); 30568 mergeCells.attr( 'count', parseFloat(mergeCells.attr( 'count' ))+1 ); 30569 $('row:eq('+(row-1)+') c', rels).attr( 's', '51' ); // centre 30570 }; 30571 30572 // Title and top messages 30573 var exportInfo = dt.buttons.exportInfo( config ); 30574 if ( exportInfo.title ) { 30575 addRow( [exportInfo.title], rowPos ); 30576 mergeCells( rowPos, data.header.length-1 ); 30577 } 30578 30579 if ( exportInfo.messageTop ) { 30580 addRow( [exportInfo.messageTop], rowPos ); 30581 mergeCells( rowPos, data.header.length-1 ); 30582 } 30583 30584 30585 // Table itself 30586 if ( config.header ) { 30587 addRow( data.header, rowPos ); 30588 $('row:last c', rels).attr( 's', '2' ); // bold 30589 } 30590 30591 dataStartRow = rowPos; 30592 30593 for ( var n=0, ie=data.body.length ; n<ie ; n++ ) { 30594 addRow( data.body[n], rowPos ); 30595 } 30596 30597 dataEndRow = rowPos; 30598 30599 if ( config.footer && data.footer ) { 30600 addRow( data.footer, rowPos); 30601 $('row:last c', rels).attr( 's', '2' ); // bold 30602 } 30603 30604 // Below the table 30605 if ( exportInfo.messageBottom ) { 30606 addRow( [exportInfo.messageBottom], rowPos ); 30607 mergeCells( rowPos, data.header.length-1 ); 30608 } 30609 30610 // Set column widths 30611 var cols = _createNode( rels, 'cols' ); 30612 $('worksheet', rels).prepend( cols ); 30613 30614 for ( var i=0, ien=data.header.length ; i<ien ; i++ ) { 30615 cols.appendChild( _createNode( rels, 'col', { 30616 attr: { 30617 min: i+1, 30618 max: i+1, 30619 width: _excelColWidth( data, i ), 30620 customWidth: 1 30621 } 30622 } ) ); 30623 } 30624 30625 // Workbook modifications 30626 var workbook = xlsx.xl['workbook.xml']; 30627 30628 $( 'sheets sheet', workbook ).attr( 'name', _sheetname( config ) ); 30629 30630 // Auto filter for columns 30631 if ( config.autoFilter ) { 30632 $('mergeCells', rels).before( _createNode( rels, 'autoFilter', { 30633 attr: { 30634 ref: 'A'+dataStartRow+':'+createCellPos(data.header.length-1)+dataEndRow 30635 } 30636 } ) ); 30637 30638 $('definedNames', workbook).append( _createNode( workbook, 'definedName', { 30639 attr: { 30640 name: '_xlnm._FilterDatabase', 30641 localSheetId: '0', 30642 hidden: 1 30643 }, 30644 text: _sheetname(config)+'!$A$'+dataStartRow+':'+createCellPos(data.header.length-1)+dataEndRow 30645 } ) ); 30646 } 30647 30648 // Let the developer customise the document if they want to 30649 if ( config.customize ) { 30650 config.customize( xlsx, config, dt ); 30651 } 30652 30653 // Excel doesn't like an empty mergeCells tag 30654 if ( $('mergeCells', rels).children().length === 0 ) { 30655 $('mergeCells', rels).remove(); 30656 } 30657 30658 var jszip = _jsZip(); 30659 var zip = new jszip(); 30660 var zipConfig = { 30661 type: 'blob', 30662 mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 30663 }; 30664 30665 _addToZip( zip, xlsx ); 30666 30667 if ( zip.generateAsync ) { 30668 // JSZip 3+ 30669 zip 30670 .generateAsync( zipConfig ) 30671 .then( function ( blob ) { 30672 _saveAs( blob, exportInfo.filename ); 30673 that.processing( false ); 30674 } ); 30675 } 30676 else { 30677 // JSZip 2.5 30678 _saveAs( 30679 zip.generate( zipConfig ), 30680 exportInfo.filename 30681 ); 30682 this.processing( false ); 30683 } 30684 }, 30685 30686 filename: '*', 30687 30688 extension: '.xlsx', 30689 30690 exportOptions: {}, 30691 30692 header: true, 30693
30694 footer: false, 30695 30696 title: '*', 30697 30698 messageTop: '*', 30699 30700 messageBottom: '*', 30701 30702 createEmptyCells: false, 30703 30704 autoFilter: false, 30705 30706 sheetName: '' 30707}; 30708 30709// 30710// PDF export - using pdfMake - http://pdfmake.org 30711// 30712DataTable.ext.buttons.pdfHtml5 = { 30713 className: 'buttons-pdf buttons-html5', 30714 30715 available: function () { 30716 return window.FileReader !== undefined && _pdfMake(); 30717 }, 30718 30719 text: function ( dt ) { 30720 return dt.i18n( 'buttons.pdf', 'PDF' ); 30721 }, 30722 30723 action: function ( e, dt, button, config ) { 30724 this.processing( true ); 30725 30726 var that = this; 30727 var data = dt.buttons.exportData( config.exportOptions ); 30728 var info = dt.buttons.exportInfo( config ); 30729 var rows = []; 30730 30731 if ( config.header ) { 30732 rows.push( $.map( data.header, function ( d ) { 30733 return { 30734 text: typeof d === 'string' ? d : d+'', 30735 style: 'tableHeader' 30736 }; 30737 } ) ); 30738 } 30739 30740 for ( var i=0, ien=data.body.length ; i<ien ; i++ ) { 30741 rows.push( $.map( data.body[i], function ( d ) { 30742 if ( d === null || d === undefined ) { 30743 d = ''; 30744 } 30745 return { 30746 text: typeof d === 'string' ? d : d+'', 30747 style: i % 2 ? 'tableBodyEven' : 'tableBodyOdd' 30748 }; 30749 } ) ); 30750 } 30751 30752 if ( config.footer && data.footer) { 30753 rows.push( $.map( data.footer, function ( d ) { 30754 return { 30755 text: typeof d === 'string' ? d : d+'', 30756 style: 'tableFooter' 30757 }; 30758 } ) ); 30759 } 30760 30761 var doc = { 30762 pageSize: config.pageSize, 30763 pageOrientation: config.orientation, 30764 content: [ 30765 { 30766 table: { 30767 headerRows: 1, 30768 body: rows 30769 }, 30770 layout: 'noBorders' 30771 } 30772 ], 30773 styles: { 30774 tableHeader: { 30775 bold: true, 30776 fontSize: 11, 30777 color: 'white', 30778 fillColor: '#2d4154', 30779 alignment: 'center' 30780 }, 30781 tableBodyEven: {}, 30782 tableBodyOdd: { 30783 fillColor: '#f3f3f3' 30784 }, 30785 tableFooter: { 30786 bold: true, 30787 fontSize: 11, 30788 color: 'white', 30789 fillColor: '#2d4154' 30790 }, 30791 title: { 30792 alignment: 'center', 30793 fontSize: 15 30794 }, 30795 message: {} 30796 }, 30797 defaultStyle: { 30798 fontSize: 10 30799 } 30800 }; 30801 30802 if ( info.messageTop ) { 30803 doc.content.unshift( { 30804 text: info.messageTop, 30805 style: 'message', 30806 margin: [ 0, 0, 0, 12 ] 30807 } ); 30808 } 30809 30810 if ( info.messageBottom ) { 30811 doc.content.push( { 30812 text: info.messageBottom, 30813 style: 'message', 30814 margin: [ 0, 0, 0, 12 ] 30815 } ); 30816 } 30817 30818 if ( info.title ) { 30819 doc.content.unshift( { 30820 text: info.title, 30821 style: 'title', 30822 margin: [ 0, 0, 0, 12 ] 30823 } ); 30824 } 30825 30826 if ( config.customize ) { 30827 config.customize( doc, config, dt ); 30828 } 30829 30830 var pdf = _pdfMake().createPdf( doc ); 30831 30832 if ( config.download === 'open' && ! _isDuffSafari() ) { 30833 pdf.open(); 30834 } 30835 else { 30836 pdf.download( info.filename ); 30837 } 30838 30839 this.processing( false ); 30840 }, 30841 30842 title: '*', 30843 30844 filename: '*', 30845 30846 extension: '.pdf', 30847 30848 exportOptions: {}, 30849 30850 orientation: 'portrait', 30851 30852 pageSize: 'A4', 30853 30854 header: true, 30855 30856 footer: false, 30857 30858 messageTop: '*', 30859 30860 messageBottom: '*', 30861 30862 customize: null, 30863 30864 download: 'download' 30865}; 30866 30867 30868return DataTable.Buttons; 30869})); 30870 30871 30872/***/ }), 30873/* 13 */ 30874/***/ (function(module, exports, __webpack_require__) { 30875 30876var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! DataTables styling wrapper for Responsive 30877 * ©2018 SpryMedia Ltd - datatables.net/license 30878 */ 30879 30880(function( factory ){ 30881 if ( true ) { 30882 // AMD 30883 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(14), __webpack_require__(15)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) { 30884 return factory( $, window, document ); 30885 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 30886 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 30887 } 30888 else {} 30889}(function( $, window, document, undefined ) { 30890 30891return $.fn.dataTable; 30892 30893})); 30894 30895/***/ }), 30896/* 14 */ 30897/***/ (function(module, exports, __webpack_require__) { 30898 30899var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! DataTables styling integration 30900 * ©2018 SpryMedia Ltd - datatables.net/license 30901 */ 30902 30903(function( factory ){ 30904 if ( true ) { 30905 // AMD 30906 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) { 30907 return factory( $, window, document ); 30908 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 30909 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 30910 } 30911 else {} 30912}(function( $, window, document, undefined ) { 30913 30914return $.fn.dataTable; 30915 30916})); 30917 30918 30919/***/ }), 30920/* 15 */ 30921/***/ (function(module, exports, __webpack_require__) { 30922 30923var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
30923/*! Responsive 2.2.9 30924 * 2014-2021 SpryMedia Ltd - datatables.net/license 30925 */ 30926 30927/** 30928 * @summary Responsive 30929 * @description Responsive tables plug-in for DataTables 30930 * @version 2.2.9 30931 * @file dataTables.responsive.js 30932 * @author SpryMedia Ltd (www.sprymedia.co.uk) 30933 * @contact www.sprymedia.co.uk/contact 30934 * @copyright Copyright 2014-2021 SpryMedia Ltd. 30935 * 30936 * This source file is free software, available under the following license: 30937 * MIT license - http://datatables.net/license/mit 30938 * 30939 * This source file is distributed in the hope that it will be useful, but 30940 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 30941 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. 30942 * 30943 * For details please refer to: http://www.datatables.net 30944 */ 30945(function( factory ){ 30946 if ( true ) { 30947 // AMD 30948 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( $ ) { 30949 return factory( $, window, document ); 30950 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 30951 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 30952 } 30953 else {} 30954}(function( $, window, document, undefined ) { 30955'use strict'; 30956var DataTable = $.fn.dataTable; 30957 30958 30959/** 30960 * Responsive is a plug-in for the DataTables library that makes use of 30961 * DataTables' ability to change the visibility of columns, changing the 30962 * visibility of columns so the displayed columns fit into the table container. 30963 * The end result is that complex tables will be dynamically adjusted to fit 30964 * into the viewport, be it on a desktop, tablet or mobile browser. 30965 * 30966 * Responsive for DataTables has two modes of operation, which can used 30967 * individually or combined: 30968 * 30969 * * Class name based control - columns assigned class names that match the 30970 * breakpoint logic can be shown / hidden as required for each breakpoint. 30971 * * Automatic control - columns are automatically hidden when there is no 30972 * room left to display them. Columns removed from the right. 30973 * 30974 * In additional to column visibility control, Responsive also has built into 30975 * options to use DataTables' child row display to show / hide the information 30976 * from the table that has been hidden. There are also two modes of operation 30977 * for this child row display: 30978 * 30979 * * Inline - when the control element that the user can use to show / hide 30980 * child rows is displayed inside the first column of the table. 30981 * * Column - where a whole column is dedicated to be the show / hide control. 30982 * 30983 * Initialisation of Responsive is performed by: 30984 * 30985 * * Adding the class `responsive` or `dt-responsive` to the table. In this case 30986 * Responsive will automatically be initialised with the default configuration 30987 * options when the DataTable is created. 30988 * * Using the `responsive` option in the DataTables configuration options. This 30989 * can also be used to specify the configuration options, or simply set to 30990 * `true` to use the defaults. 30991 * 30992 * @class 30993 * @param {object} settings DataTables settings object for the host table 30994 * @param {object} [opts] Configuration options 30995 * @requires jQuery 1.7+ 30996 * @requires DataTables 1.10.3+ 30997 * 30998 * @example 30999 * $('#example').DataTable( { 31000 * responsive: true 31001 * } ); 31002 * } ); 31003 */ 31004var Responsive = function ( settings, opts ) { 31005 // Sanity check that we are using DataTables 1.10 or newer 31006 if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.10' ) ) { 31007 throw 'DataTables Responsive requires DataTables 1.10.10 or newer'; 31008 } 31009 31010 this.s = { 31011 dt: new DataTable.Api( settings ), 31012 columns: [], 31013 current: [] 31014 }; 31015 31016 // Check if responsive has already been initialised on this table 31017 if ( this.s.dt.settings()[0].responsive ) { 31018 return; 31019 } 31020 31021 // details is an object, but for simplicity the user can give it as a string 31022 // or a boolean 31023 if ( opts && typeof opts.details === 'string' ) { 31024 opts.details = { type: opts.details }; 31025 } 31026 else if ( opts && opts.details === false ) { 31027 opts.details = { type: false }; 31028 } 31029 else if ( opts && opts.details === true ) { 31030 opts.details = { type: 'inline' }; 31031 } 31032 31033 this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts ); 31034 settings.responsive = this; 31035 this._constructor(); 31036}; 31037 31038$.extend( Responsive.prototype, { 31039 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 31040 * Constructor 31041 */ 31042 31043 /** 31044 * Initialise the Responsive instance 31045 * 31046 * @private 31047 */ 31048 _constructor: function () 31049 { 31050 var that = this; 31051 var dt = this.s.dt; 31052 var dtPrivateSettings = dt.settings()[0]; 31053 var oldWindowWidth = $(window).innerWidth(); 31054 31055 dt.settings()[0]._responsive = this; 31056 31057 // Use DataTables' throttle function to avoid processor thrashing on 31058 // resize 31059 $(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () { 31060 // iOS has a bug whereby resize can fire when only scrolling 31061 // See: http://stackoverflow.com/questions/8898412 31062 var width = $(window).innerWidth(); 31063 31064 if ( width !== oldWindowWidth ) { 31065 that._resize(); 31066 oldWindowWidth = width; 31067 } 31068 } ) ); 31069 31070 // DataTables doesn't currently trigger an event when a row is added, so 31071 // we need to hook into its private API to enforce the hidden rows when 31072 // new data is added 31073 dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) { 31074 if ( $.inArray( false, that.s.current ) !== -1 ) { 31075 $('>td, >th', tr).each( function ( i ) { 31076 var idx = dt.column.index( 'toData', i ); 31077 31078 if ( that.s.current[idx] === false ) { 31079 $(this).css('display', 'none'); 31080 } 31081 } ); 31082 } 31083 } ); 31084 31085 // Destroy event handler 31086 dt.on( 'destroy.dtr', function () { 31087 dt.off( '.dtr' ); 31088 $( dt.table().body() ).off( '.dtr' ); 31089 $(window).off( 'resize.dtr orientationchange.dtr' ); 31090 dt.cells('.dtr-control').nodes().to$().removeClass('dtr-control'); 31091 31092 // Restore the columns that we've hidden
31093 $.each( that.s.current, function ( i, val ) { 31094 if ( val === false ) { 31095 that._setColumnVis( i, true ); 31096 } 31097 } ); 31098 } ); 31099 31100 // Reorder the breakpoints array here in case they have been added out 31101 // of order 31102 this.c.breakpoints.sort( function (a, b) { 31103 return a.width < b.width ? 1 : 31104 a.width > b.width ? -1 : 0; 31105 } ); 31106 31107 this._classLogic(); 31108 this._resizeAuto(); 31109 31110 // Details handler 31111 var details = this.c.details; 31112 31113 if ( details.type !== false ) { 31114 that._detailsInit(); 31115 31116 // DataTables will trigger this event on every column it shows and 31117 // hides individually 31118 dt.on( 'column-visibility.dtr', function () { 31119 // Use a small debounce to allow multiple columns to be set together 31120 if ( that._timer ) { 31121 clearTimeout( that._timer ); 31122 } 31123 31124 that._timer = setTimeout( function () { 31125 that._timer = null; 31126 31127 that._classLogic(); 31128 that._resizeAuto(); 31129 that._resize(true); 31130 31131 that._redrawChildren(); 31132 }, 100 ); 31133 } ); 31134 31135 // Redraw the details box on each draw which will happen if the data 31136 // has changed. This is used until DataTables implements a native 31137 // `updated` event for rows 31138 dt.on( 'draw.dtr', function () { 31139 that._redrawChildren(); 31140 } ); 31141 31142 $(dt.table().node()).addClass( 'dtr-'+details.type ); 31143 } 31144 31145 dt.on( 'column-reorder.dtr', function (e, settings, details) { 31146 that._classLogic(); 31147 that._resizeAuto(); 31148 that._resize(true); 31149 } ); 31150 31151 // Change in column sizes means we need to calc 31152 dt.on( 'column-sizing.dtr', function () { 31153 that._resizeAuto(); 31154 that._resize(); 31155 }); 31156 31157 // On Ajax reload we want to reopen any child rows which are displayed 31158 // by responsive 31159 dt.on( 'preXhr.dtr', function () { 31160 var rowIds = []; 31161 dt.rows().every( function () { 31162 if ( this.child.isShown() ) { 31163 rowIds.push( this.id(true) ); 31164 } 31165 } ); 31166 31167 dt.one( 'draw.dtr', function () { 31168 that._resizeAuto(); 31169 that._resize(); 31170 31171 dt.rows( rowIds ).every( function () { 31172 that._detailsDisplay( this, false ); 31173 } ); 31174 } ); 31175 }); 31176 31177 dt 31178 .on( 'draw.dtr', function () { 31179 that._controlClass(); 31180 }) 31181 .on( 'init.dtr', function (e, settings, details) { 31182 if ( e.namespace !== 'dt' ) { 31183 return; 31184 } 31185 31186 that._resizeAuto(); 31187 that._resize(); 31188 31189 // If columns were hidden, then DataTables needs to adjust the 31190 // column sizing 31191 if ( $.inArray( false, that.s.current ) ) { 31192 dt.columns.adjust(); 31193 } 31194 } ); 31195 31196 // First pass - draw the table for the current viewport size 31197 this._resize(); 31198 }, 31199 31200 31201 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 31202 * Private methods 31203 */ 31204 31205 /** 31206 * Calculate the visibility for the columns in a table for a given 31207 * breakpoint. The result is pre-determined based on the class logic if 31208 * class names are used to control all columns, but the width of the table 31209 * is also used if there are columns which are to be automatically shown 31210 * and hidden. 31211 * 31212 * @param {string} breakpoint Breakpoint name to use for the calculation 31213 * @return {array} Array of boolean values initiating the visibility of each 31214 * column. 31215 * @private 31216 */ 31217 _columnsVisiblity: function ( breakpoint ) 31218 { 31219 var dt = this.s.dt; 31220 var columns = this.s.columns; 31221 var i, ien; 31222 31223 // Create an array that defines the column ordering based first on the 31224 // column's priority, and secondly the column index. This allows the 31225 // columns to be removed from the right if the priority matches 31226 var order = columns 31227 .map( function ( col, idx ) { 31228 return { 31229 columnIdx: idx, 31230 priority: col.priority 31231 }; 31232 } ) 31233 .sort( function ( a, b ) { 31234 if ( a.priority !== b.priority ) { 31235 return a.priority - b.priority; 31236 } 31237 return a.columnIdx - b.columnIdx; 31238 } ); 31239 31240 // Class logic - determine which columns are in this breakpoint based 31241 // on the classes. If no class control (i.e. `auto`) then `-` is used 31242 // to indicate this to the rest of the function 31243 var display = $.map( columns, function ( col, i ) { 31244 if ( dt.column(i).visible() === false ) { 31245 return 'not-visible'; 31246 } 31247 return col.auto && col.minWidth === null ? 31248 false : 31249 col.auto === true ? 31250 '-' : 31251 $.inArray( breakpoint, col.includeIn ) !== -1; 31252 } ); 31253 31254 // Auto column control - first pass: how much width is taken by the 31255 // ones that must be included from the non-auto columns 31256 var requiredWidth = 0; 31257 for ( i=0, ien=display.length ; i<ien ; i++ ) { 31258 if ( display[i] === true ) { 31259 requiredWidth += columns[i].minWidth; 31260 } 31261 } 31262 31263 // Second pass, use up any remaining width for other columns. For 31264 // scrolling tables we need to subtract the width of the scrollbar. It
31265 // may not be requires which makes this sub-optimal, but it would 31266 // require another full redraw to make complete use of those extra few 31267 // pixels 31268 var scrolling = dt.settings()[0].oScroll; 31269 var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0; 31270 var widthAvailable = dt.table().container().offsetWidth - bar; 31271 var usedWidth = widthAvailable - requiredWidth; 31272 31273 // Control column needs to always be included. This makes it sub- 31274 // optimal in terms of using the available with, but to stop layout 31275 // thrashing or overflow. Also we need to account for the control column 31276 // width first so we know how much width is available for the other 31277 // columns, since the control column might not be the first one shown 31278 for ( i=0, ien=display.length ; i<ien ; i++ ) { 31279 if ( columns[i].control ) { 31280 usedWidth -= columns[i].minWidth; 31281 } 31282 } 31283 31284 // Allow columns to be shown (counting by priority and then right to 31285 // left) until we run out of room 31286 var empty = false; 31287 for ( i=0, ien=order.length ; i<ien ; i++ ) { 31288 var colIdx = order[i].columnIdx; 31289 31290 if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) { 31291 // Once we've found a column that won't fit we don't let any 31292 // others display either, or columns might disappear in the 31293 // middle of the table 31294 if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) { 31295 empty = true; 31296 display[colIdx] = false; 31297 } 31298 else { 31299 display[colIdx] = true; 31300 } 31301 31302 usedWidth -= columns[colIdx].minWidth; 31303 } 31304 } 31305 31306 // Determine if the 'control' column should be shown (if there is one). 31307 // This is the case when there is a hidden column (that is not the 31308 // control column). The two loops look inefficient here, but they are 31309 // trivial and will fly through. We need to know the outcome from the 31310 // first , before the action in the second can be taken 31311 var showControl = false; 31312 31313 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 31314 if ( ! columns[i].control && ! columns[i].never && display[i] === false ) { 31315 showControl = true; 31316 break; 31317 } 31318 } 31319 31320 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 31321 if ( columns[i].control ) { 31322 display[i] = showControl; 31323 } 31324 31325 // Replace not visible string with false from the control column detection above 31326 if ( display[i] === 'not-visible' ) { 31327 display[i] = false; 31328 } 31329 } 31330 31331 // Finally we need to make sure that there is at least one column that 31332 // is visible 31333 if ( $.inArray( true, display ) === -1 ) { 31334 display[0] = true; 31335 } 31336
31337 return display; 31338 }, 31339 31340 31341 /** 31342 * Create the internal `columns` array with information about the columns 31343 * for the table. This includes determining which breakpoints the column 31344 * will appear in, based upon class names in the column, which makes up the 31345 * vast majority of this method. 31346 * 31347 * @private 31348 */ 31349 _classLogic: function () 31350 { 31351 var that = this; 31352 var calc = {}; 31353 var breakpoints = this.c.breakpoints; 31354 var dt = this.s.dt; 31355 var columns = dt.columns().eq(0).map( function (i) { 31356 var column = this.column(i); 31357 var className = column.header().className; 31358 var priority = dt.settings()[0].aoColumns[i].responsivePriority; 31359 var dataPriority = column.header().getAttribute('data-priority'); 31360 31361 if ( priority === undefined ) { 31362 priority = dataPriority === undefined || dataPriority === null? 31363 10000 : 31364 dataPriority * 1; 31365 } 31366 31367 return { 31368 className: className, 31369 includeIn: [], 31370 auto: false, 31371 control: false, 31372 never: className.match(/\bnever\b/) ? true : false, 31373 priority: priority 31374 }; 31375 } ); 31376 31377 // Simply add a breakpoint to `includeIn` array, ensuring that there are 31378 // no duplicates 31379 var add = function ( colIdx, name ) { 31380 var includeIn = columns[ colIdx ].includeIn; 31381 31382 if ( $.inArray( name, includeIn ) === -1 ) { 31383 includeIn.push( name ); 31384 } 31385 }; 31386 31387 var column = function ( colIdx, name, operator, matched ) { 31388 var size, i, ien; 31389 31390 if ( ! operator ) { 31391 columns[ colIdx ].includeIn.push( name ); 31392 } 31393 else if ( operator === 'max-' ) { 31394 // Add this breakpoint and all smaller 31395 size = that._find( name ).width; 31396 31397 for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) { 31398 if ( breakpoints[i].width <= size ) { 31399 add( colIdx, breakpoints[i].name ); 31400 } 31401 } 31402 } 31403 else if ( operator === 'min-' ) { 31404 // Add this breakpoint and all larger 31405 size = that._find( name ).width; 31406 31407 for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) { 31408 if ( breakpoints[i].width >= size ) { 31409 add( colIdx, breakpoints[i].name ); 31410 } 31411 } 31412 } 31413 else if ( operator === 'not-' ) { 31414 // Add all but this breakpoint 31415 for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) { 31416 if ( breakpoints[i].name.indexOf( matched ) === -1 ) { 31417 add( colIdx, breakpoints[i].name ); 31418 } 31419 } 31420 } 31421 }; 31422 31423 // Loop over each column and determine if it has a responsive control 31424 // class 31425 columns.each( function ( col, i ) { 31426 var classNames = col.className.split(' '); 31427 var hasClass = false; 31428 31429 // Split the class name up so multiple rules can be applied if needed 31430 for ( var k=0, ken=classNames.length ; k<ken ; k++ ) { 31431 var className = classNames[k].trim(); 31432 31433 if ( className === 'all' ) { 31434 // Include in all 31435 hasClass = true; 31436 col.includeIn = $.map( breakpoints, function (a) { 31437 return a.name; 31438 } ); 31439 return; 31440 } 31441 else if ( className === 'none' || col.never ) { 31442 // Include in none (default) and no auto 31443 hasClass = true; 31444 return; 31445 } 31446 else if ( className === 'control' || className === 'dtr-control' ) { 31447 // Special column that is only visible, when one of the other 31448 // columns is hidden. This is used for the details control 31449 hasClass = true; 31450 col.control = true; 31451 return; 31452 } 31453 31454 $.each( breakpoints, function ( j, breakpoint ) { 31455 // Does this column have a class that matches this breakpoint? 31456 var brokenPoint = breakpoint.name.split('-'); 31457 var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' ); 31458 var match = className.match( re ); 31459 31460 if ( match ) { 31461 hasClass = true; 31462 31463 if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) { 31464 // Class name matches breakpoint name fully 31465 column( i, breakpoint.name, match[1], match[2]+match[3] ); 31466 } 31467 else if ( match[2] === brokenPoint[0] && ! match[3] ) { 31468 // Class name matched primary breakpoint name with no qualifier 31469 column( i, breakpoint.name, match[1], match[2] ); 31470 } 31471 } 31472 } ); 31473 } 31474 31475 // If there was no control class, then automatic sizing is used 31476 if ( ! hasClass ) { 31477 col.auto = true; 31478 } 31479 } ); 31480 31481 this.s.columns = columns; 31482 }, 31483 31484 /** 31485 * Update the cells to show the correct control class / button 31486 * @private 31487 */ 31488 _controlClass: function () 31489 { 31490 if ( this.c.details.type === 'inline' ) { 31491 var dt = this.s.dt; 31492 var columnsVis = this.s.current; 31493 var firstVisible = $.inArray(true, columnsVis); 31494 31495 // Remove from any cells which shouldn't have it 31496 dt.cells( 31497 null, 31498 function(idx) { 31499 return idx !== firstVisible; 31500 }, 31501 {page: 'current'} 31502 ) 31503 .nodes() 31504 .to$() 31505 .filter('.dtr-control') 31506 .removeClass('dtr-control'); 31507 31508 dt.cells(null, firstVisible, {page: 'current'}) 31509 .nodes() 31510 .to$() 31511 .addClass('dtr-control'); 31512 } 31513 }, 31514 31515 /** 31516 * Show the details for the child row 31517 * 31518 * @param {DataTables.Api} row API instance for the row 31519 * @param {boolean} update Update flag 31520 * @private 31521 */ 31522 _detailsDisplay: function ( row, update ) 31523 { 31524 var that = this; 31525 var dt = this.s.dt; 31526 var details = this.c.details; 31527 31528 if ( details && details.type !== false ) { 31529 var res = details.display( row, update, function () { 31530 return details.renderer( 31531 dt, row[0], that._detailsObj(row[0]) 31532 ); 31533 } ); 31534 31535 if ( res === true || res === false ) { 31536 $(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] ); 31537 } 31538 } 31539 }, 31540 31541 31542 /** 31543 * Initialisation for the details handler 31544 * 31545 * @private 31546 */ 31547 _detailsInit: function () 31548 { 31549 var that = this; 31550 var dt = this.s.dt; 31551 var details = this.c.details; 31552 31553 // The inline type always uses the first child as the target 31554 if ( details.type === 'inline' ) { 31555 details.target = 'td.dtr-control, th.dtr-control'; 31556 } 31557 31558 // Keyboard accessibility 31559 dt.on( 'draw.dtr', function () { 31560 that._tabIndexes(); 31561 } ); 31562 that._tabIndexes(); // Initial draw has already happened 31563 31564 $( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) { 31565 if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) { 31566 $(this).click(); 31567 } 31568 } ); 31569 31570 // type.target can be a string jQuery selector or a column index 31571 var target = details.target; 31572 var selector = typeof target === 'string' ? target : 'td, th'; 31573 31574 if ( target !== undefined || target !== null ) { 31575 // Click handler to show / hide the details rows when they are available 31576 $( dt.table().body() ) 31577 .on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) { 31578 // If the table is not collapsed (i.e. there is no hidden columns) 31579 // then take no action 31580 if ( ! $(dt.table().node()).hasClass('collapsed' ) ) { 31581 return; 31582 } 31583 31584 // Check that the row is actually a DataTable's controlled node 31585 if ( $.inArray( $(this).closest('tr').get(0), dt.rows().nodes().toArray() ) === -1 ) { 31586 return; 31587 } 31588 31589 // For column index, we determine if we should act or not in the 31590 // handler - otherwise it is already okay 31591 if ( typeof target === 'number' ) { 31592 var targetIdx = target < 0 ? 31593 dt.columns().eq(0).length + target : 31594 target; 31595 31596 if ( dt.cell( this ).index().column !== targetIdx ) { 31597 return; 31598 } 31599 } 31600
31601 // $().closest() includes itself in its check 31602 var row = dt.row( $(this).closest('tr') ); 31603 31604 // Check event type to do an action 31605 if ( e.type === 'click' ) { 31606 // The renderer is given as a function so the caller can execute it 31607 // only when they need (i.e. if hiding there is no point is running 31608 // the renderer) 31609 that._detailsDisplay( row, false ); 31610 } 31611 else if ( e.type === 'mousedown' ) { 31612 // For mouse users, prevent the focus ring from showing 31613 $(this).css('outline', 'none'); 31614 } 31615 else if ( e.type === 'mouseup' ) { 31616 // And then re-allow at the end of the click 31617 $(this).trigger('blur').css('outline', ''); 31618 } 31619 } ); 31620 } 31621 }, 31622 31623 31624 /** 31625 * Get the details to pass to a renderer for a row 31626 * @param {int} rowIdx Row index 31627 * @private 31628 */ 31629 _detailsObj: function ( rowIdx ) 31630 { 31631 var that = this; 31632 var dt = this.s.dt; 31633 31634 return $.map( this.s.columns, function( col, i ) { 31635 // Never and control columns should not be passed to the renderer 31636 if ( col.never || col.control ) { 31637 return; 31638 } 31639 31640 var dtCol = dt.settings()[0].aoColumns[ i ]; 31641 31642 return { 31643 className: dtCol.sClass, 31644 columnIndex: i, 31645 data: dt.cell( rowIdx, i ).render( that.c.orthogonal ), 31646 hidden: dt.column( i ).visible() && !that.s.current[ i ], 31647 rowIndex: rowIdx, 31648 title: dtCol.sTitle !== null ? 31649 dtCol.sTitle : 31650 $(dt.column(i).header()).text() 31651 }; 31652 } ); 31653 }, 31654 31655 31656 /** 31657 * Find a breakpoint object from a name 31658 * 31659 * @param {string} name Breakpoint name to find 31660 * @return {object} Breakpoint description object 31661 * @private 31662 */ 31663 _find: function ( name ) 31664 { 31665 var breakpoints = this.c.breakpoints; 31666 31667 for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) { 31668 if ( breakpoints[i].name === name ) { 31669 return breakpoints[i]; 31670 } 31671 } 31672 }, 31673 31674 31675 /** 31676 * Re-create the contents of the child rows as the display has changed in 31677 * some way. 31678 * 31679 * @private 31680 */ 31681 _redrawChildren: function () 31682 { 31683 var that = this; 31684 var dt = this.s.dt; 31685 31686 dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) { 31687 var row = dt.row( idx ); 31688 31689 that._detailsDisplay( dt.row( idx ), true ); 31690 } ); 31691 }, 31692 31693 31694 /** 31695 * Alter the table display for a resized viewport. This involves first 31696 * determining what breakpoint the window currently is in, getting the 31697 * column visibilities to apply and then setting them. 31698 * 31699 * @param {boolean} forceRedraw Force a redraw 31700 * @private 31701 */ 31702 _resize: function (forceRedraw) 31703 { 31704 var that = this; 31705 var dt = this.s.dt; 31706 var width = $(window).innerWidth(); 31707 var breakpoints = this.c.breakpoints; 31708 var breakpoint = breakpoints[0].name; 31709 var columns = this.s.columns; 31710 var i, ien; 31711 var oldVis = this.s.current.slice(); 31712 31713 // Determine what breakpoint we are currently at 31714 for ( i=breakpoints.length-1 ; i>=0 ; i-- ) { 31715 if ( width <= breakpoints[i].width ) { 31716 breakpoint = breakpoints[i].name; 31717 break; 31718 } 31719 } 31720 31721 // Show the columns for that break point 31722 var columnsVis = this._columnsVisiblity( breakpoint ); 31723 this.s.current = columnsVis; 31724 31725 // Set the class before the column visibility is changed so event 31726 // listeners know what the state is. Need to determine if there are 31727 // any columns that are not visible but can be shown 31728 var collapsedClass = false; 31729 31730 for ( i=0, ien=columns.length ; i<ien ; i++ ) { 31731 if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control && ! dt.column(i).visible() === false ) { 31732 collapsedClass = true; 31733 break; 31734 } 31735 } 31736 31737 $( dt.table().node() ).toggleClass( 'collapsed', collapsedClass ); 31738 31739 var changed = false; 31740 var visible = 0; 31741 31742 dt.columns().eq(0).each( function ( colIdx, i ) { 31743 if ( columnsVis[i] === true ) { 31744 visible++; 31745 } 31746 31747 if ( forceRedraw || columnsVis[i] !== oldVis[i] ) { 31748 changed = true; 31749 that._setColumnVis( colIdx, columnsVis[i] ); 31750 } 31751 } ); 31752 31753 if ( changed ) { 31754 this._redrawChildren(); 31755 31756 // Inform listeners of the change 31757 $(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] ); 31758 31759 // If no records, update the "No records" display element 31760 if ( dt.page.info().recordsDisplay === 0 ) { 31761 $('td', dt.table().body()).eq(0).attr('colspan', visible); 31762 } 31763 } 31764 31765 that._controlClass(); 31766 }, 31767 31768 31769 /** 31770 * Determine the width of each column in the table so the auto column hiding 31771 * has that information to work with. This method is never going to be 100% 31772 * perfect since column widths can change slightly per page, but without 31773 * seriously compromising performance this is quite effective. 31774 * 31775 * @private 31776 */ 31777 _resizeAuto: function () 31778 { 31779 var dt = this.s.dt; 31780 var columns = this.s.columns; 31781 31782 // Are we allowed to do auto sizing? 31783 if ( ! this.c.auto ) { 31784 return; 31785 } 31786 31787 // Are there any columns that actually need auto-sizing, or do they all 31788 // have classes defined 31789 if ( $.inArray( true, $.map( columns, function (c) { return c.auto; }
31789 ) ) === -1 ) { 31790 return; 31791 } 31792 31793 // Need to restore all children. They will be reinstated by a re-render 31794 if ( ! $.isEmptyObject( _childNodeStore ) ) { 31795 $.each( _childNodeStore, function ( key ) { 31796 var idx = key.split('-'); 31797 31798 _childNodesRestore( dt, idx[0]*1, idx[1]*1 ); 31799 } ); 31800 } 31801 31802 // Clone the table with the current data in it 31803 var tableWidth = dt.table().node().offsetWidth; 31804 var columnWidths = dt.columns; 31805 var clonedTable = dt.table().node().cloneNode( false ); 31806 var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable ); 31807 var clonedBody = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8 31808 31809 clonedTable.style.width = 'auto'; 31810 31811 // Header 31812 var headerCells = dt.columns() 31813 .header() 31814 .filter( function (idx) { 31815 return dt.column(idx).visible(); 31816 } ) 31817 .to$() 31818 .clone( false ) 31819 .css( 'display', 'table-cell' ) 31820 .css( 'width', 'auto' ) 31821 .css( 'min-width', 0 ); 31822 31823 // Body rows - we don't need to take account of DataTables' column 31824 // visibility since we implement our own here (hence the `display` set) 31825 $(clonedBody) 31826 .append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) ) 31827 .find( 'th, td' ).css( 'display', '' ); 31828 31829 // Footer 31830 var footer = dt.table().footer(); 31831 if ( footer ) { 31832 var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable ); 31833 var footerCells = dt.columns() 31834 .footer() 31835 .filter( function (idx) { 31836 return dt.column(idx).visible(); 31837 } ) 31838 .to$() 31839 .clone( false ) 31840 .css( 'display', 'table-cell' ); 31841 31842 $('<tr/>') 31843 .append( footerCells ) 31844 .appendTo( clonedFooter ); 31845 } 31846 31847 $('<tr/>') 31848 .append( headerCells ) 31849 .appendTo( clonedHeader ); 31850 31851 // In the inline case extra padding is applied to the first column to 31852 // give space for the show / hide icon. We need to use this in the 31853 // calculation 31854 if ( this.c.details.type === 'inline' ) { 31855 $(clonedTable).addClass( 'dtr-inline collapsed' ); 31856 } 31857 31858 // It is unsafe to insert elements with the same name into the DOM 31859 // multiple times. For example, cloning and inserting a checked radio 31860 // clears the chcecked state of the original radio. 31861 $( clonedTable ).find( '[name]' ).removeAttr( 'name' ); 31862 31863 // A position absolute table would take the table out of the flow of 31864 // our container element, bypassing the height and width (Scroller) 31865 $( clonedTable ).css( 'position', 'relative' ) 31866 31867 var inserted = $('<div/>') 31868 .css( { 31869 width: 1, 31870 height: 1, 31871 overflow: 'hidden', 31872 clear: 'both' 31873 } ) 31874 .append( clonedTable ); 31875 31876 inserted.insertBefore( dt.table().node() ); 31877 31878 // The cloned header now contains the smallest that each column can be 31879 headerCells.each( function (i) { 31880 var idx = dt.column.index( 'fromVisible', i ); 31881 columns[ idx ].minWidth = this.offsetWidth || 0; 31882 } ); 31883 31884 inserted.remove(); 31885 }, 31886 31887 /** 31888 * Get the state of the current hidden columns - controlled by Responsive only 31889 */ 31890 _responsiveOnlyHidden: function () 31891 { 31892 var dt = this.s.dt; 31893 31894 return $.map( this.s.current, function (v, i) { 31895 // If the column is hidden by DataTables then it can't be hidden by 31896 // Responsive! 31897 if ( dt.column(i).visible() === false ) { 31898 return true; 31899 } 31900 return v; 31901 } ); 31902 }, 31903 31904 /** 31905 * Set a column's visibility. 31906 * 31907 * We don't use DataTables' column visibility controls in order to ensure 31908 * that column visibility can Responsive can no-exist. Since only IE8+ is 31909 * supported (and all evergreen browsers of course) the control of the 31910 * display attribute works well. 31911 * 31912 * @param {integer} col Column index 31913 * @param {boolean} showHide Show or hide (true or false) 31914 * @private 31915 */ 31916 _setColumnVis: function ( col, showHide ) 31917 { 31918 var dt = this.s.dt; 31919 var display = showHide ? '' : 'none'; // empty string will remove the attr 31920 31921 $( dt.column( col ).header() ).css( 'display', display ); 31922 $( dt.column( col ).footer() ).css( 'display', display ); 31923 dt.column( col ).nodes().to$().css( 'display', display ); 31924 31925 // If the are child nodes stored, we might need to reinsert them 31926 if ( ! $.isEmptyObject( _childNodeStore ) ) { 31927 dt.cells( null, col ).indexes().each( function (idx) { 31928 _childNodesRestore( dt, idx.row, idx.column ); 31929 } ); 31930 } 31931 }, 31932 31933 31934 /** 31935 * Update the cell tab indexes for keyboard accessibility. This is called on 31936 * every table draw - that is potentially inefficient, but also the least 31937 * complex option given that column visibility can change on the fly. Its a 31938 * shame user-focus was removed from CSS 3 UI, as it would have solved this 31939 * issue with a single CSS statement. 31940 * 31941 * @private 31942 */ 31943 _tabIndexes: function () 31944 { 31945 var dt = this.s.dt; 31946 var cells = dt.cells( { page: 'current' } ).nodes().to$(); 31947 var ctx = dt.settings()[0]; 31948 var target = this.c.details.target; 31949 31950 cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' ); 31951 31952 if ( typeof target === 'number' ) { 31953 dt.cells( null, target, { page: 'current' } ).nodes().to$() 31954 .attr( 'tabIndex', ctx.iTabIndex ) 31955 .data( 'dtr-keyboard', 1 ); 31956 } 31957 else { 31958 // This is a bit of a hack - we need to limit the selected nodes to just 31959 // those of this table 31960 if ( target === 'td:first-child, th:first-child' ) { 31961 target = '>td:first-child, >th:first-child'; 31962 } 31963 31964 $( target, dt.rows( { page: 'current' } ).nodes() ) 31965 .attr( 'tabIndex', ctx.iTabIndex ) 31966 .data( 'dtr-keyboard', 1 ); 31967 } 31968 } 31969} ); 31970 31971 31972/** 31973 * List of default breakpoints. Each item in the array is an object with two 31974 * properties: 31975 * 31976 * * `name` - the breakpoint name. 31977 * * `width` - the breakpoint width 31978 * 31979 * @name Responsive.breakpoints 31980 * @static 31981 */ 31982Responsive.breakpoints = [ 31983 { name: 'desktop', width: Infinity }, 31984 { name: 'tablet-l', width: 1024 }, 31985 { name: 'tablet-p', width: 768 }, 31986 { name: 'mobile-l', width: 480 }, 31987 { name: 'mobile-p', width: 320 } 31988]; 31989 31990 31991/** 31992 * Display methods - functions which define how the hidden data should be shown 31993 * in the table. 31994 * 31995 * @namespace 31996 * @name Responsive.defaults 31997 * @static 31998 */ 31999Responsive.display = { 32000 childRow: function ( row, update, render ) { 32001 if ( update ) { 32002 if ( $(row.node()).hasClass('parent') ) { 32003 row.child( render(), 'child' ).show(); 32004 32005 return true; 32006 } 32007 } 32008 else { 32009 if ( ! row.child.isShown() ) { 32010 row.child( render(), 'child' ).show(); 32011 $( row.node() ).addClass( 'parent' ); 32012 32013 return true; 32014 } 32015 else { 32016 row.child( false ); 32017 $( row.node() ).removeClass( 'parent' ); 32018 32019 return false;
32020 } 32021 } 32022 }, 32023 32024 childRowImmediate: function ( row, update, render ) { 32025 if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) { 32026 // User interaction and the row is show, or nothing to show 32027 row.child( false ); 32028 $( row.node() ).removeClass( 'parent' ); 32029 32030 return false; 32031 } 32032 else { 32033 // Display 32034 row.child( render(), 'child' ).show(); 32035 $( row.node() ).addClass( 'parent' ); 32036 32037 return true; 32038 } 32039 }, 32040 32041 // This is a wrapper so the modal options for Bootstrap and jQuery UI can 32042 // have options passed into them. This specific one doesn't need to be a 32043 // function but it is for consistency in the `modal` name 32044 modal: function ( options ) { 32045 return function ( row, update, render ) { 32046 if ( ! update ) { 32047 // Show a modal 32048 var close = function () { 32049 modal.remove(); // will tidy events for us 32050 $(document).off( 'keypress.dtr' ); 32051 }; 32052 32053 var modal = $('<div class="dtr-modal"/>') 32054 .append( $('<div class="dtr-modal-display"/>') 32055 .append( $('<div class="dtr-modal-content"/>') 32056 .append( render() ) 32057 ) 32058 .append( $('<div class="dtr-modal-close">×</div>' ) 32059 .click( function () { 32060 close(); 32061 } ) 32062 ) 32063 ) 32064 .append( $('<div class="dtr-modal-background"/>') 32065 .click( function () { 32066 close(); 32067 } ) 32068 ) 32069 .appendTo( 'body' ); 32070 32071 $(document).on( 'keyup.dtr', function (e) { 32072 if ( e.keyCode === 27 ) { 32073 e.stopPropagation(); 32074 32075 close(); 32076 } 32077 } ); 32078 } 32079 else { 32080 $('div.dtr-modal-content') 32081 .empty() 32082 .append( render() ); 32083 } 32084 32085 if ( options && options.header ) { 32086 $('div.dtr-modal-content').prepend( 32087 '<h2>'+options.header( row )+'</h2>' 32088 ); 32089 } 32090 }; 32091 } 32092}; 32093 32094 32095var _childNodeStore = {}; 32096 32097function _childNodes( dt, row, col ) { 32098 var name = row+'-'+col; 32099 32100 if ( _childNodeStore[ name ] ) { 32101 return _childNodeStore[ name ]; 32102 } 32103 32104 // https://jsperf.com/childnodes-array-slice-vs-loop 32105 var nodes = []; 32106 var children = dt.cell( row, col ).node().childNodes; 32107 for ( var i=0, ien=children.length ; i<ien ; i++ ) { 32108 nodes.push( children[i] ); 32109 } 32110 32111 _childNodeStore[ name ] = nodes; 32112 32113 return nodes; 32114} 32115 32116function _childNodesRestore( dt, row, col ) { 32117 var name = row+'-'+col; 32118 32119 if ( ! _childNodeStore[ name ] ) { 32120 return; 32121 } 32122 32123 var node = dt.cell( row, col ).node(); 32124 var store = _childNodeStore[ name ]; 32125 var parent = store[0].parentNode; 32126 var parentChildren = parent.childNodes; 32127 var a = []; 32128 32129 for ( var i=0, ien=parentChildren.length ; i<ien ; i++ ) { 32130 a.push( parentChildren[i] ); 32131 } 32132 32133 for ( var j=0, jen=a.length ; j<jen ; j++ ) { 32134 node.appendChild( a[j] ); 32135 } 32136 32137 _childNodeStore[ name ] = undefined; 32138} 32139 32140 32141/** 32142 * Display methods - functions which define how the hidden data should be shown 32143 * in the table. 32144 * 32145 * @namespace 32146 * @name Responsive.defaults 32147 * @static 32148 */ 32149Responsive.renderer = { 32150 listHiddenNodes: function () { 32151 return function ( api, rowIdx, columns ) { 32152 var ul = $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>'); 32153 var found = false; 32154 32155 var data = $.each( columns, function ( i, col ) { 32156 if ( col.hidden ) { 32157 var klass = col.className ? 32158 'class="'+ col.className +'"' : 32159 ''; 32160 32161 $( 32162 '<li '+klass+' data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+ 32163 '<span class="dtr-title">'+ 32164 col.title+ 32165 '</span> '+ 32166 '</li>' 32167 ) 32168 .append( $('<span class="dtr-data"/>').append( _childNodes( api, col.rowIndex, col.columnIndex ) ) )// api.cell( col.rowIndex, col.columnIndex ).node().childNodes ) ) 32169 .appendTo( ul ); 32170 32171 found = true; 32172 } 32173 } ); 32174 32175 return found ? 32176 ul : 32177 false; 32178 }; 32179 }, 32180 32181 listHidden: function () { 32182 return function ( api, rowIdx, columns ) { 32183 var data = $.map( columns, function ( col ) { 32184 var klass = col.className ? 32185 'class="'+ col.className +'"' : 32186 ''; 32187 32188 return col.hidden ? 32189 '<li '+klass+' data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+ 32190 '<span class="dtr-title">'+ 32191 col.title+ 32192 '</span> '+ 32193 '<span class="dtr-data">'+ 32194 col.data+ 32195 '</span>'+ 32196 '</li>' : 32197 ''; 32198 } ).join(''); 32199 32200 return data ? 32201 $('<ul data-dtr-index="'+rowIdx+'" class="dtr-details"/>').append( data ) : 32202 false; 32203 } 32204 }, 32205 32206 tableAll: function ( options ) { 32207 options = $.extend( { 32208 tableClass: '' 32209 }, options ); 32210 32211 return function ( api, rowIdx, columns ) { 32212 var data = $.map( columns, function ( col ) { 32213 var klass = col.className ? 32214 'class="'+ col.className +'"' : 32215 ''; 32216 32217 return '<tr '+klass+' data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+ 32218 '<td>'+col.title+':'+'</td> '+ 32219 '<td>'+col.data+'</td>'+ 32220 '</tr>'; 32221 } ).join(''); 32222 32223 return $('<table class="'+options.tableClass+' dtr-details" width="100%"/>').append( data ); 32224 } 32225 } 32226}; 32227 32228/** 32229 * Responsive default settings for initialisation 32230 * 32231 * @namespace 32232 * @name Responsive.defaults 32233 * @static 32234 */ 32235Responsive.defaults = { 32236 /** 32237 * List of breakpoints for the instance. Note that this means that each 32238 * instance can have its own breakpoints. Additionally, the breakpoints 32239 * cannot be changed once an instance has been creased. 32240 * 32241 * @type {Array} 32242 * @default Takes the value of `Responsive.breakpoints` 32243 */ 32244 breakpoints: Responsive.breakpoints, 32245 32246 /** 32247 * Enable / disable auto hiding calculations. It can help to increase 32248 * performance slightly if you disable this option, but all columns would 32249 * need to have breakpoint classes assigned to them 32250 * 32251 * @type {Boolean} 32252 * @default `true` 32253 */ 32254 auto: true, 32255 32256 /** 32257 * Details control. If given as a string value, the `type` property of the 32258 * default object is set to that value, and the defaults used for the rest 32259 * of the object - this is for ease of implementation. 32260 *
32261 * The object consists of the following properties: 32262 * 32263 * * `display` - A function that is used to show and hide the hidden details 32264 * * `renderer` - function that is called for display of the child row data. 32265 * The default function will show the data from the hidden columns 32266 * * `target` - Used as the selector for what objects to attach the child 32267 * open / close to 32268 * * `type` - `false` to disable the details display, `inline` or `column` 32269 * for the two control types 32270 * 32271 * @type {Object|string} 32272 */ 32273 details: { 32274 display: Responsive.display.childRow, 32275 32276 renderer: Responsive.renderer.listHidden(), 32277 32278 target: 0, 32279 32280 type: 'inline' 32281 }, 32282 32283 /** 32284 * Orthogonal data request option. This is used to define the data type 32285 * requested when Responsive gets the data to show in the child row. 32286 * 32287 * @type {String} 32288 */ 32289 orthogonal: 'display' 32290}; 32291 32292 32293/* 32294 * API 32295 */ 32296var Api = $.fn.dataTable.Api; 32297 32298// Doesn't do anything - work around for a bug in DT... Not documented 32299Api.register( 'responsive()', function () { 32300 return this; 32301} ); 32302 32303Api.register( 'responsive.index()', function ( li ) { 32304 li = $(li); 32305 32306 return { 32307 column: li.data('dtr-index'), 32308 row: li.parent().data('dtr-index') 32309 }; 32310} ); 32311 32312Api.register( 'responsive.rebuild()', function () { 32313 return this.iterator( 'table', function ( ctx ) { 32314 if ( ctx._responsive ) { 32315 ctx._responsive._classLogic(); 32316 } 32317 } ); 32318} ); 32319 32320Api.register( 'responsive.recalc()', function () { 32321 return this.iterator( 'table', function ( ctx ) { 32322 if ( ctx._responsive ) { 32323 ctx._responsive._resizeAuto(); 32324 ctx._responsive._resize(); 32325 } 32326 } ); 32327} ); 32328 32329Api.register( 'responsive.hasHidden()', function () { 32330 var ctx = this.context[0]; 32331 32332 return ctx._responsive ? 32333 $.inArray( false, ctx._responsive._responsiveOnlyHidden() ) !== -1 : 32334 false; 32335} ); 32336 32337Api.registerPlural( 'columns().responsiveHidden()', 'column().responsiveHidden()', function () { 32338 return this.iterator( 'column', function ( settings, column ) { 32339 return settings._responsive ?
32340 settings._responsive._responsiveOnlyHidden()[ column ] : 32341 false; 32342 }, 1 ); 32343} ); 32344 32345 32346/** 32347 * Version information 32348 * 32349 * @name Responsive.version 32350 * @static 32351 */ 32352Responsive.version = '2.2.9'; 32353 32354 32355$.fn.dataTable.Responsive = Responsive; 32356$.fn.DataTable.Responsive = Responsive; 32357 32358// Attach a listener to the document which listens for DataTables initialisation 32359// events so we can automatically initialise 32360$(document).on( 'preInit.dt.dtr', function (e, settings, json) { 32361 if ( e.namespace !== 'dt' ) { 32362 return; 32363 } 32364 32365 if ( $(settings.nTable).hasClass( 'responsive' ) || 32366 $(settings.nTable).hasClass( 'dt-responsive' ) || 32367 settings.oInit.responsive || 32368 DataTable.defaults.responsive 32369 ) { 32370 var init = settings.oInit.responsive; 32371 32372 if ( init !== false ) { 32373 new Responsive( settings, $.isPlainObject( init ) ? init : {} ); 32374 } 32375 } 32376} ); 32377 32378 32379return Responsive; 32380})); 32381 32382 32383/***/ }), 32384/* 16 */ 32385/***/ (function(module, exports, __webpack_require__) { 32386 32387/* WEBPACK VAR INJECTION */(function(Buffer, global, setImmediate) {var require;var require;/*! 32388 32389JSZip v3.7.1 - A JavaScript class for generating and reading zip files 32390<http://stuartk.com/jszip> 32391 32392(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com> 32393Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. 32394 32395JSZip uses the library pako released under the MIT license : 32396https://github.com/nodeca/pako/blob/master/LICENSE 32397*/ 32398 32399!function(t){if(true)module.exports=t();else {}}(function(){return function s(a,o,h){function u(r,t){if(!o[r]){if(!a[r]){var e="function"==typeof require&&require;if(!t&&e)return requir
vendor: 5,404 bytes, line 32399
32399e(r,!0);if(l)return l(r,!0);var i=new Error("Cannot find module '"+r+"'");throw i.code="MODULE_NOT_FOUND",i}var n=o[r]={exports:{}};a[r][0].call(n.exports,function(t){var e=a[r][1][t];return u(e||t)},n,n.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,t=0;t<h.length;t++)u(h[t]);return u}({1:[function(t,e,r){"use strict";var c=t("./utils"),d=t("./support"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.encode=function(t){for(var e,r,i,n,s,a,o,h=[],u=0,l=t.length,f=l,d="string"!==c.getTypeOf(t);u<t.length;)f=l-u,i=d?(e=t[u++],r=u<l?t[u++]:0,u<l?t[u++]:0):(e=t.charCodeAt(u++),r=u<l?t.charCodeAt(u++):0,u<l?t.charCodeAt(u++):0),n=e>>2,s=(3&e)<<4|r>>4,a=1<f?(15&r)<<2|i>>6:64,o=2<f?63&i:64,h.push(p.charAt(n)+p.charAt(s)+p.charAt(a)+p.charAt(o));return h.join("")},r.decode=function(t){var e,r,i,n,s,a,o=0,h=0,u="data:";if(t.substr(0,u.length)===u)throw new Error("Invalid base64 input, it looks like a data url.");var l,f=3*(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"")).length/4;if(t.charAt(t.length-1)===p.charAt(64)&&f--,t.charAt(t.length-2)===p.charAt(64)&&f--,f%1!=0)throw new Error("Invalid base64 input, bad content length.");for(l=d.uint8array?new Uint8Array(0|f):new Array(0|f);o<t.length;)e=p.indexOf(t.charAt(o++))<<2|(n=p.indexOf(t.charAt(o++)))>>4,r=(15&n)<<4|(s=p.indexOf(t.charAt(o++)))>>2,i=(3&s)<<6|(a=p.indexOf(t.charAt(o++))),l[h++]=e,64!==s&&(l[h++]=r),64!==a&&(l[h++]=i);return l}},{"./support":30,"./utils":32}],2:[function(t,e,r){"use strict";var i=t("./external"),n=t("./stream/DataWorker"),s=t("./stream/Crc32Probe"),a=t("./stream/DataLengthProbe");function o(t,e,r,i,n){this.compressedSize=t,this.uncompressedSize=e,this.crc32=r,this.compression=i,this.compressedContent=n}o.prototype={getContentWorker:function(){var t=new n(i.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),e=this;return t.on("end",function(){if(this.streamInfo.data_length!==e.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),t},getCompressedWorker:function(){return new n(i.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(t,e,r){return t.pipe(new s).pipe(new a("uncompressedSize")).pipe(e.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",e)},e.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(t,e,r){"use strict";var i=t("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(t){return new i("STORE compression")},uncompressWorker:function(){return new i("STORE decompression")}},r.DEFLATE=t("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(t,e,r){"use strict";var i=t("./utils");var o=function(){for(var t,e=[],r=0;r<256;r++){t=r;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[r]=t}return e}();e.exports=function(t,e){return void 0!==t&&t.length?"string"!==i.getTypeOf(t)?function(t,e,r,i){var n=o,s=i+r;t^=-1;for(var a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return-1^t}(0|e,t,t.length,0):function(t,e,r,i){var n=o,s=i+r;t^=-1;for(var a=i;a<s;a++)t=t>>>8^n[255&(t^e.charCodeAt(a))];return-1^t}(0|e,t,t.length,0):0}},{"./utils":32}],5:[function(t,e,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(t,e,r){"use strict";var i=null;i="undefined"!=typeof Promise?Promise:t("lie"),e.exports={Promise:i}},{lie:37}],7:[function(t,e,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,n=t("pako"),s=t("./utils"),a=t("./stream/GenericWorker"),o=i?"uint8array":"array";function h(t,e){a.call(this,"FlateWorker/"+t),this._pako=null,this._pakoAction=t,this._pakoOptions=e,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(t){this.meta=t.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,t.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new n[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var e=this;this._pako.onData=function(t){e.push({data:t,meta:e.meta})}},r.compressWorker=function(t){return new h("Deflate",t)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(t,e,r){"use strict";function A(t,e){var r,i="";for(r=0;r<e;r++)i+=String.fromCharCode(255&t),t>>>=8;return i}function i(t,e,r,i,n,s){var a,o,h=t.file,u=t.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),d=I.transformTo("string",O.utf8encode(h.name)),c=h.comment,p=I.transformTo("string",s(c)),m=I.transformTo("string",O.utf8encode(c)),_=d.length!==h.name.length,g=m.length!==c.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};e&&!r||(x.crc32=t.crc32,x.compressedSize=t.compressedSize,x.uncompressedSize=t.uncompressedSize);var S=0;
vendor: 89,589 bytes, line 32399
32399e&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===n?(C=798,z|=function(t,e){var r=t;return t||(r=e?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(t){return 63&(t||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+d,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(i,4)+f+b+p}}var I=t("../utils"),n=t("../stream/GenericWorker"),O=t("../utf8"),B=t("../crc32"),R=t("../signature");function s(t,e,r,i){n.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=e,this.zipPlatform=r,this.encodeFileName=i,this.streamFiles=t,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,n),s.prototype.push=function(t){var e=t.meta.percent||0,r=this.entriesCount,i=this._sources.length;this.accumulate?this.contentBuffer.push(t):(this.bytesWritten+=t.data.length,n.prototype.push.call(this,{data:t.data,meta:{currentFile:this.currentFile,percent:r?(e+100*(r-i-1))/r:100}}))},s.prototype.openedSource=function(t){this.currentSourceOffset=this.bytesWritten,this.currentFile=t.file.name;var e=this.streamFiles&&!t.file.dir;if(e){var r=i(t,e,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(t){this.accumulate=!1;var e=this.streamFiles&&!t.file.dir,r=i(t,e,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),e)this.push({data:function(t){return R.DATA_DESCRIPTOR+A(t.crc32,4)+A(t.compressedSize,4)+A(t.uncompressedSize,4)}(t),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var t=this.bytesWritten,e=0;e<this.dirRecords.length;e++)this.push({data:this.dirRecords[e],meta:{percent:100}});var r=this.bytesWritten-t,i=function(t,e,r,i,n){var s=I.transformTo("string",n(i));return R.CENTRAL_DIRECTORY_END+"\0\0\0\0"+A(t,2)+A(t,2)+A(e,4)+A(r,4)+A(s.length,2)+s}(this.dirRecords.length,r,t,this.zipComment,this.encodeFileName);this.push({data:i,meta:{percent:100}})},s.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},s.prototype.registerPrevious=function(t){this._sources.push(t);var e=this;return t.on("data",function(t){e.processChunk(t)}),t.on("end",function(){e.closedSource(e.previous.streamInfo),e._sources.length?e.prepareNextSource():e.end()}),t.on("error",function(t){e.error(t)}),this},s.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},s.prototype.error=function(t){var e=this._sources;if(!n.prototype.error.call(this,t))return!1;for(var r=0;r<e.length;r++)try{e[r].error(t)}catch(t){}return!0},s.prototype.lock=function(){n.prototype.lock.call(this);for(var t=this._sources,e=0;e<t.length;e++)t[e].lock()},e.exports=s},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(t,e,r){"use strict";var u=t("../compressions"),i=t("./ZipFileWorker");r.generateWorker=function(t,a,e){var o=new i(a.streamFiles,e,a.platform,a.encodeFileName),h=0;try{t.forEach(function(t,e){h++;var r=function(t,e){var r=t||e,i=u[r];if(!i)throw new Error(r+" is not a valid compression method !");return i}(e.options.compression,a.compression),i=e.options.compressionOptions||a.compressionOptions||{},n=e.dir,s=e.date;e._compressWorker(r,i).withStreamInfo("file",{name:t,dir:n,date:s,comment:e.comment||"",unixPermissions:e.unixPermissions,dosPermissions:e.dosPermissions}).pipe(o)}),o.entriesCount=h}catch(t){o.error(t)}return o}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(t,e,r){"use strict";function i(){if(!(this instanceof i))return new i;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files=Object.create(null),this.comment=null,this.root="",this.clone=function(){var t=new i;for(var e in this)"function"!=typeof this[e]&&(t[e]=this[e]);return t}}(i.prototype=t("./object")).loadAsync=t("./load"),i.support=t("./support"),i.defaults=t("./defaults"),i.version="3.7.1",i.loadAsync=function(t,e){return(new i).loadAsync(t,e)},i.external=t("./external"),e.exports=i},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(t,e,r){"use strict";var i=t("./utils"),n=t("./external"),o=t("./utf8"),h=t("./zipEntries"),s=t("./stream/Crc32Probe"),u=t("./nodejsUtils");function l(i){return new n.Promise(function(t,e){var r=i.decompressed.getContentWorker().pipe(new s);r.on("error",function(t){e(t)}).on("end",function(){r.streamInfo.crc32!==i.decompressed.crc32?e(new Error("Corrupted zip : CRC32 mismatch")):t()}).resume()})}e.exports=function(t,s){var a=this;return s=i.extend(s||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:o.utf8decode}),u.isNode&&u.isStream(t)?n.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):i.prepareContent("the loaded zip file",t,!0,s.optimizedBinaryString,s.base64).then(function(t){var e=new h(s);return e.load(t),e}).then(function(t){var e=[n.Promise.resolve(t)],r=t.files;if(s.checkCRC32)for(var i=0;i<r.length;i++)e.push(l(r[i]));return n.Promise.all(e)}).then(function(t){for(var e=t.shift(),r=e.files,i=0;i<r.length;i++){var n=r[i];a.file(n.fileNameStr,n.decompressed,{binary:!0,optimizedBinaryString:!0,date:n.date,dir:n.dir,comment:n.fileCommentStr.length?n.fileCommentStr:null,unixPermissions:n.unixPermissions,dosPermissions:n.dosPermissions,createFolders:s.createFolders})}return e.zipComment.length&&(a.comment=e.zipComment),a})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(t,e,r){"use strict";var i=t("../utils"),n=t("../stream/GenericWorker");function s(t,e){n.call(this,"Nodejs stream input adapter for "+t),this._upstreamEnded=!1,this._bindStream(e)}i.inherits(s,n),s.prototype._bindStream=function(t){var e=this;(this._stream=t).pause(),t.on("data",function(t){e.push({data:t,meta:{percent:0}})}).on("error",function(t){e.isPaused?this.generatedError=t:e.error(t)}).on("end",function(){e.isPaused?e._upstreamEnded=!0:e.end()})},s.prototype.pause=function(){return!!n.prototype.pause.call(this)&&(this._stream.pause(),!0)},s.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},e.exports=s},{"../stream/GenericWorker":28,"../utils":32}],13:[function(t,e,r){"use strict";var n=t("readable-stream").Readable;function i(t,e,r){n.call(this,e),this._helper=t;var i=this;t.on("data",function(t,e){i.push(t)||i._helper.pause(),r&&r(e)}).on("error",function(t){i.emit("error",t)}).on("end",function(){i.push(null)})}t("../utils").inherits(i,n),i.prototype._read=function(){this._helper.resume()},e.exports=i},{"../utils":32,"readable-stream":16}],14:[function(t,e,r){"use strict";e.exports={isNode:"undefined"!=typeof Buffer,newBufferFrom:function(t,e){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(t,e);if("number"==typeof t)throw new Error('The "data" argument must not be a number');return new Buffer(t,e)},allocBuffer:function(t){if(Buffer.alloc)return Buffer.alloc(t);var e=new Buffer(t);return e.fill(0),e},isBuffer:function(t){return Buffer.isBuffer(t)},isStream:function(t){return t&&"function"==typeof t.on&&"function"==typeof t.pause&&"function"==typeof t.resume}}},{}],15:[function(t,e,r){"use strict";function s(t,e,r){var i,n=u.getTypeOf(e),s=u.extend(r||{},f);s.date=s.date||new Date,null!==s.compression&&(s.compression=s.compression.toUpperCase()),"string"==typeof s.unixPermissions&&(s.unixPermissions=parseInt(s.unixPermissions,8)),s.unixPermissions&&16384&s.unixPermissions&&(s.dir=!0),s.dosPermissions&&16&s.dosPermissions&&(s.dir=!0),s.dir&&(t=g(t)),s.createFolders&&(i=_(t))&&b.call(this,i,!0);var a="string"===n&&!1===s.binary&&!1===s.base64;r&&void 0!==r.binary||(s.binary=!a),(e instanceof d&&0===e.uncompressedSize||s.dir||!e||0===e.length)&&(s.base64=!1,s.binary=!0,e="",s.compression="STORE",n="string");var o=null;o=e instanceof d||e instanceof l?e:p.isNode&&p.isStream(e)?new m(t,e):u.prepareContent(t,e,s.binary,s.optimizedBinaryString,s.base64);var h=new c(t,o,s);this.files[t]=h}var n=t("./utf8"),u=t("./utils"),l=t("./stream/GenericWorker"),a=t("./stream/StreamHelper"),f=t("./defaults"),d=t("./compressedObject"),c=t("./zipObject"),o=t("./generate"),p=t("./nodejsUtils"),m=t("./nodejs/NodejsStreamInputAdapter"),_=function(t){"/"===t.slice(-1)&&(t=t.substring(0,t.length-1));var e=t.lastIndexOf("/");return 0<e?t.substring(0,e):""},g=function(t){return"/"!==t.slice(-1)&&(t+="/"),t},b=function(t,e){return e=void 0!==e?e:f.createFolders,t=g(t),this.files[t]||s.call(this,t,null,{dir:!0,createFolders:e}),this.files[t]};function h(t){return"[object RegExp]"===Object.prototype.toString.call(t)}var i={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(t){var e,r,i;for(e in this.files)i=this.files[e],(r=e.slice(this.root.length,e.length))&&e.slice(0,this.root.length)===this.root&&t(r,i)},filter:function(r){var i=[];return this.forEach(function(t,e){r(t,e)&&i.push(e)}),i},file:function(t,e,r){if(1!==arguments.length)return t=this.root+t,s.call(this,t,e,r),this;if(h(t)){var i=t;return this.filter(function(t,e){return!e.dir&&i.test(t)})}var n=this.files[this.root+t];return n&&!n.dir?n:null},folder:function(r){if(!r)return this;if(h(r))return this.filter(function(t,e){return e.dir&&r.test(t)});var t=this.root+r,e=b.call(this,t),i=this.clone();return i.root=e.name,i},remove:function(r){r=this.root+r;var t=this.files[r];if(t||("/"!==r.slice(-1)&&(r+="/"),t=this.files[r]),t&&!t.dir)delete this.files[r];else for(var e=this.filter(function(t,e){return e.name.slice(0,r.length)===r}),i=0;i<e.length;i++)delete this.files[e[i].name];return this},generate:function(t){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(t){var e,r={};try{if((r=u.extend(t||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:n.utf8encode})).type=r.type.toLowerCase(),r.compression=r.compression.toUpperCase(),"binarystring"===r.type&&(r.type="string"),!r.type)throw new Error("No output type specified.");u.checkSupport(r.type),"darwin"!==r.platform&&"freebsd"!==r.platform&&"linux"!==r.platform&&"sunos"!==r.platform||(r.platform="UNIX"),"win32"===r.platform&&(r.platform="DOS");var i=r.comment||this.comment||"";e=o.generateWorker(this,r,i)}catch(t){(e=new l("error")).error(t)}return new a(e,r.type||"string",r.mimeType)},generateAsync:function(t,e){return this.generateInternalStream(t).accumulate(e)},generateNodeStream:function(t,e){return(t=t||{}).type||(t.type="nodebuffer"),this.generateInternalStream(t).toNodejsStream(e)}};e.exports=i},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(t,e,r){e.exports=t("stream")},{stream:void 0}],17:[function(t,e,r){"use strict";var i=t("./DataReader");function n(t){i.call(this,t);for(var e=0;e<this.data.length;e++)t[e]=255&t[e]}t("../utils").inherits(n,i),n.prototype.byteAt=function(t){return this.data[this.zero+t]},n.prototype.lastIndexOfSignature=function(t){for(var e=t.charCodeAt(0),r=t.charCodeAt(1),i=t.charCodeAt(2),n=t.charCodeAt(3),s=this.length-4;0<=s;--s)if(this.data[s]===e&&this.data[s+1]===r&&this.data[s+2]===i&&this.data[s+3]===n)return s-this.zero;return-1},n.prototype.readAndCheckSignature=function(t){var e=t.charCodeAt(0),r=t.charCodeAt(1),i=t.charCodeAt(2),n=t.charCodeAt(3),s=this.readData(4);return e===s[0]&&r===s[1]&&i===s[2]&&n===s[3]},n.prototype.readData=function(t){if(this.checkOffset(t),0===t)return[];var e=this.data.slice(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./DataReader":18}],18:[function(t,e,r){"use strict";var i=t("../utils");function n(t){this.data=t,this.length=t.length,this.index=0,this.zero=0}n.prototype={checkOffset:function(t){this.checkIndex(this.index+t)},checkIndex:function(t){if(this.length<this.zero+t||t<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+t+"). Corrupted zip ?")},setIndex:function(t){this.checkIndex(t),this.index=t},skip:function(t){this.setIndex(this.index+t)},byteAt:function(t){},readInt:function(t){var e,r=0;for(this.checkOffset(t),e=this.index+t-1;e>=this.index;e--)r=(r<<8)+this.byteAt(e);return this.index+=t,r},readString:function(t){return i.transformTo("string",this.readData(t))},readData:function(t){},lastIndexOfSignature:function(t){},readAndCheckSignature:function(t){},readDate:function(){var t=this.readInt(4);return new Date(Date.UTC(1980+(t>>25&127),(t>>21&15)-1,t>>16&31,t>>11&31,t>>5&63,(31&t)<<1))}},e.exports=n},{"../utils":32}],19:[function(t,e,r){"use strict";var i=t("./Uint8ArrayReader");function n(t){i.call(this,t)}t("../utils").inherits(n,i),n.prototype.readData=function(t){this.checkOffset(t);var e=this.data.slice(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(t,e,r){"use strict";var i=t("./DataReader");function n(t){i.call(this,t)}t("../utils").inherits(n,i),n.prototype.byteAt=function(t){return this.data.charCodeAt(this.zero+t)},n.prototype.lastIndexOfSignature=function(t){return this.data.lastIndexOf(t)-this.zero},n.prototype.readAndCheckSignature=function(t){return t===this.readData(4)},n.prototype.readData=function(t){this.checkOffset(t);var e=this.data.slice(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./DataReader":18}],21:[function(t,e,r){"use strict";var i=t("./ArrayReader");function n(t){i.call(this,t)}t("../utils").inherits(n,i),n.prototype.readData=function(t){if(this.checkOffset(t),0===t)return new Uint8Array(0);var e=this.data.subarray(this.zero+this.index,this.zero+this.index+t);return this.index+=t,e},e.exports=n},{"../utils":32,"./ArrayReader":17}],22:[function(t,e,r){"use strict";var i=t("../utils"),n=t("../support"),s=t("./ArrayReader"),a=t("./StringReader"),o=t("./NodeBufferReader"),h=t("./Uint8ArrayReader");e.exports=function(t){var e=i.getTypeOf(t);return i.checkSupport(e),"string"!==e||n.uint8array?"nodebuffer"===e?new o(t):n.uint8array?new h(i.transformTo("uint8array",t)):new s(i.transformTo("array",t)):new a(t)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(t,e,r){"use strict";r.LOCAL_FILE_HEADER="PK��",r.CENTRAL_FILE_HEADER="PK��",r.CENTRAL_DIRECTORY_END="PK��",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK��",r.ZIP64_CENTRAL_DIRECTORY_END="PK��",r.DATA_DESCRIPTOR="PK�\b"},{}],24:[function(t,e,r){"use strict";var i=t("./GenericWorker"),n=t("../utils");function s(t){i.call(this,"ConvertWorker to "+t),this.destType=t}n.inherits(s,i),s.prototype.processChunk=function(t){this.push({data:n.transformTo(this.destType,t.data),meta:t.meta})},e.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(t,e,r){"use strict";var i=t("./GenericWorker"),n=t("../crc32");function s(){i.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}t("../utils").inherits(s,i),s.prototype.processChunk=function(t){this.streamInfo.crc32=n(t.data,this.streamInfo.crc32||0),this.push(t)},e.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(t,e,r){"use strict";var i=t("../utils"),n=t("./GenericWorker");function s(t){n.call(this,"DataLengthProbe for "+t),this.propName=t,this.withStreamInfo(t,0)}i.inherits(s,n),s.prototype.processChunk=function(t){if(t){var e=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=e+t.data.length}n.prototype.processChunk.call(this,t)},e.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(t,e,r){"use strict";var i=t("../utils"),n=t("./GenericWorker");function s(t){n.call(this,"DataWorker");var e=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,t.then(function(t){e.dataIsReady=!0,e.data=t,e.max=t&&t.length||0,e.type=i.getTypeOf(t),e.isPaused||e._tickAndRepeat()},function(t){e.error(t)})}i.inherits(s,n),s.prototype.cleanUp=function(){n.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!n.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,i.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(i.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var t=null,e=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":t=this.data.substring(this.index,e);break;case"uint8array":t=this.data.subarray(this.index,e);break;case"array":case"nodebuffer":t=this.data.slice(this.index,e)}return this.index=e,this.push({data:t,meta:{percent:this.max?this.index/this.max*100:0}})},e.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(t,e,r){"use strict";function i(t){this.name=t||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}i.prototype={push:function(t){this.emit("data",t)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(t){this.emit("error",t)}return!0},error:function(t){return!this.isFinished&&(this.isPaused?this.generatedError=t:(this.isFinished=!0,this.emit("error",t),this.previous&&this.previous.error(t),this.cleanUp()),!0)},on:function(t,e){return this._listeners[t].push(e),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(t,e){if(this._listeners[t])for(var r=0;r<this._listeners[t].length;r++)this._listeners[t][r].call(this,e)},pipe:function(t){return t.registerPrevious(this)},registerPrevious:function(t){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=t.streamInfo,this.mergeStreamInfo(),this.previous=t;var e=this;return t.on("data",function(t){e.processChunk(t)}),t.on("end",function(){e.end()}),t.on("error",function(t){e.error(t)}),this},pause:function(){return!this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return!1;var t=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),t=!0),this.previous&&this.previous.resume(),!t},flush:function(){},processChunk:function(t){this.push(t)},withStreamInfo:function(t,e){return this.extraStreamInfo[t]=e,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var t in this.extraStreamInfo)this.extraStreamInfo.hasOwnProperty(t)&&(this.streamInfo[t]=this.extraStreamInfo[t])},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock()},toString:function(){var t="Worker "+this.name;return this.previous?this.previous+" -> "+t:t}},e.exports=i},{}],29:[function(t,e,r){"use strict";var h=t("../utils"),n=t("./ConvertWorker"),s=t("./GenericWorker"),u=t("../base64"),i=t("../support"),a=t("../external"),o=null;if(i.nodestream)try{o=t("../nodejs/NodejsStreamOutputAdapter")}catch(t){}function l(t,o){return new a.Promise(function(e,r){var i=[],n=t._internalType,s=t._outputType,a=t._mimeType;t.on("data",function(t,e){i.push(t),o&&o(e)}).on("error",function(t){i=[],r(t)}).on("end",function(){try{var t=function(t,e,r){switch(t){case"blob":return h.newBlob(h.transformTo("arraybuffer",e),r);case"base64":return u.encode(e);default:return h.transformTo(t,e)}}(s,function(t,e){var r,i=0,n=null,s=0;for(r=0;r<e.length;r++)s+=e[r].length;switch(t){case"string":return e.join("");case"array":return Array.prototype.concat.apply([],e);case"uint8array":for(n=new Uint8Array(s),r=0;r<e.length;r++)n.set(e[r],i),i+=e[r].length;return n;case"nodebuffer":return Buffer.concat(e);default:throw new Error("concat : unsupported type '"+t+"'")}}(n,i),a);e(t)}catch(t){r(t)}i=[]}).resume()})}function f(t,e,r){var i=e;switch(e){case"blob":case"arraybuffer":i="uint8array";break;case"base64":i="string"}try{this._internalType=i,this._outputType=e,this._mimeType=r,h.checkSupport(i),this._worker=t.pipe(new n(i)),t.lock()}catch(t){this._worker=new s("error"),this._worker.error(t)}}f.prototype={accumulate:function(t){return l(this,t)},on:function(t,e){var r=this;return"data"===t?this._worker.on(t,function(t){e.call(r,t.data,t.meta)}):this._worker.on(t,function(){h.delay(e,arguments,r)}),this},resume:function(){return h.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(t){if(h.checkSupport("nodestream"),"nodebuffer"!==this._outputType)throw new Error(this._outputType+" is not supported by this method");return new o(this,{objectMode:"nodebuffer"!==this._outputType},t)}},e.exports=f},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(t,e,r){"use strict";if(r.base64=!0,r.array=!0,r.string=!0,r.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,r.nodebuffer="undefined"!=typeof Buffer,r.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)r.blob=!1;else{var i=new ArrayBuffer(0);try{r.blob=0===new Blob([i],{type:"application/zip"}).size}catch(t){try{var n=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);n.append(i),r.blob=0===n.getBlob("application/zip").size}catch(t){r.blob=!1}}}try{r.nodestream=!!t("readable-stream").Readable}catch(t){r.nodestream=!1}},{"readable-stream":16}],31:[function(t,e,s){"use strict";for(var o=t("./utils"),h=t("./support"),r=t("./nodejsUtils"),i=t("./stream/GenericWorker"),u=new Array(256),n=0;n<256;n++)u[n]=252<=n?6:248<=n?5:240<=n?4:224<=n?3:192<=n?2:1;u[254]=u[254]=1;function a(){i.call(this,"utf-8 decode"),this.leftOver=null}function l(){i.call(this,"utf-8 encode")}s.utf8encode=function(t){return h.nodebuffer?r.newBufferFrom(t,"utf-8"):function(t){var e,r,i,n,s,a=t.length,o=0;for(n=0;n<a;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),o+=r<128?1:r<2048?2:r<65536?3:4;for(e=h.uint8array?new Uint8Array(o):new Array(o),n=s=0;s<o;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),r<128?e[s++]=r:(r<2048?e[s++]=192|r>>>6:(r<65536?e[s++]=224|r>>>12:(e[s++]=240|r>>>18,e[s++]=128|r>>>12&63),e[s++]=128|r>>>6&63),e[s++]=128|63&r);return e}(t)},s.utf8decode=function(t){return h.nodebuffer?o.transformTo("nodebuffer",t).toString("utf-8"):function(t){var e,r,i,n,s=t.length,a=new Array(2*s);for(e=r=0;e<s;)if((i=t[e++])<128)a[r++]=i;else if(4<(n=u[i]))a[r++]=65533,e+=n-1;else{for(i&=2===n?31:3===n?15:7;1<n&&e<s;)i=i<<6|63&t[e++],n--;1<n?a[r++]=65533:i<65536?a[r++]=i:(i-=65536,a[r++]=55296|i>>10&1023,a[r++]=56320|1023&i)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(t=o.transformTo(h.uint8array?"uint8array":"array",t))},o.inherits(a,i),a.prototype.processChunk=function(t){var e=o.transformTo(h.uint8array?"uint8array":"array",t.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=e;(e=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),e.set(r,this.leftOver.length)}else e=this.leftOver.concat(e);this.leftOver=null}var i=function(t,e){var r;for((e=e||t.length)>t.length&&(e=t.length),r=e-1;0<=r&&128==(192&t[r]);)r--;return r<0?e:0===r?e:r+u[t[r]]>e?r:e}(e),n=e;i!==e.length&&(h.uint8array?(n=e.subarray(0,i),this.leftOver=e.subarray(i,e.length)):(n=e.slice(0,i),this.leftOver=e.slice(i,e.length))),this.push({data:s.utf8decode(n),meta:t.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,i),l.prototype.processChunk=function(t){this.push({data:s.utf8encode(t.data),meta:t.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(t,e,a){"use strict";var o=t("./support"),h=t("./base64"),r=t("./nodejsUtils"),i=t("set-immediate-shim"),u=t("./external");function n(t){return t}function l(t,e){for(var r=0;r<t.length;++r)e[r]=255&t.charCodeAt(r);return e}a.newBlob=function(e,r){a.checkSupport("blob");try{return new Blob([e],{type:r})}catch(t){try{var i=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return i.append(e),i.getBlob(r)}catch(t){throw new Error("Bug : can't construct the Blob.")}}};var s={stringifyByChunk:function(t,e,r){var i=[],n=0,s=t.length;if(s<=r)return String.fromCharCode.apply(null,t);for(;n<s;)"array"===e||"nodebuffer"===e?i.push(String.fromCharCode.apply(null,t.slice(n,Math.min(n+r,s)))):i.push(String.fromCharCode.apply(null,t.subarray(n,Math.min(n+r,s)))),n+=r;return i.join("")},stringifyByChar:function(t){for(var e="",r=0;r<t.length;r++)e+=String.fromCharCode(t[r]);return e},applyCanBeUsed:{uint8array:function(){try{return o.uint8array&&1===String.fromCharCode.apply(null,new Uint8Array(1)).length}catch(t){return!1}}(),nodebuffer:function(){try{return o.nodebuffer&&1===String.fromCharCode.apply(null,r.allocBuffer(1)).length}catch(t){return!1}}()}};function f(t){var e=65536,r=a.getTypeOf(t),i=!0;if("uint8array"===r?i=s.applyCanBeUsed.uint8array:"nodebuffer"===r&&(i=s.applyCanBeUsed.nodebuffer),i)for(;1<e;)try{return s.stringifyByChunk(t,r,e)}catch(t){e=Math.floor(e/2)}return s.stringifyByChar(t)}function d(t,e){for(var r=0;r<t.length;r++)e[r]=t[r];return e}a.applyFromCharCode=f;var c={};c.string={string:n,array:function(t){return l(t,new Array(t.length))},arraybuffer:function(t){return c.string.uint8array(t).buffer},uint8array:function(t){return l(t,new Uint8Array(t.length))},nodebuffer:function(t){return l(t,r.allocBuffer(t.length))}},c.array={string:f,array:n,arraybuffer:function(t){return new Uint8Array(t).buffer},uint8array:function(t){return new Uint8Array(t)},nodebuffer:function(t){return r.newBufferFrom(t)}},c.arraybuffer={string:function(t){return f(new Uint8Array(t))},array:function(t){return d(new Uint8Array(t),new Array(t.byteLength))},arraybuffer:n,uint8array:function(t){return new Uint8Array(t)},nodebuffer:function(t){return r.newBufferFrom(new Uint8Array(t))}},c.uint8array={string:f,array:function(t){return d(t,new Array(t.length))},arraybuffer:function(t){return t.buffer},uint8array:n,nodebuffer:function(t){return r.newBufferFrom(t)}},c.nodebuffer={string:f,array:function(t){return d(t,new Array(t.length))},arraybuffer:function(t){return c.nodebuffer.uint8array(t).buffer},uint8array:function(t){return d(t,new Uint8Array(t.length))},nodebuffer:n},a.transformTo=function(t,e){if(e=e||"",!t)return e;a.checkSupport(t);var r=a.getTypeOf(e);return c[r][t](e)},a.getTypeOf=function(t){return"string"==typeof t?"string":"[object Array]"===Object.prototype.toString.call(t)?"array":o.nodebuffer&&r.isBuffer(t)?"nodebuffer":o.uint8array&&t instanceof Uint8Array?"uint8array":o.arraybuffer&&t instanceof ArrayBuffer?"arraybuffer":void 0},a.checkSupport=function(t){if(!o[t.toLowerCase()])throw new Error(t+" is not supported by this platform")},a.MAX_VALUE_16BITS=65535,a.MAX_VALUE_32BITS=-1,a.pretty=function(t){var e,r,i="";for(r=0;r<(t||"").length;r++)i+="\\x"+((e=t.charCodeAt(r))<16?"0":"")+e.toString(16).toUpperCase();return i},a.delay=function(t,e,r){i(function(){t.apply(r||null,e||[])})},a.inherits=function(t,e){function r(){}r.prototype=e.prototype,t.prototype=new r},a.extend=function(){var t,e,r={};for(t=0;t<arguments.length;t++)for(e in arguments[t])arguments[t].hasOwnProperty(e)&&void 0===r[e]&&(r[e]=arguments[t][e]);return r},a.prepareContent=function(r,t,i,n,s){return u.Promise.resolve(t).then(function(i){return o.blob&&(i instanceof Blob||-1!==["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(i)))&&"undefined"!=typeof FileReader?new u.Promise(function(e,r){var t=new FileReader;t.onload=function(t){e(t.target.result)},t.onerror=function(t){r(t.target.error)},t.readAsArrayBuffer(i)}):i}).then(function(t){var e=a.getTypeOf(t);return e?("arraybuffer"===e?t=a.transformTo("uint8array",t):"string"===e&&(s?t=h.decode(t):i&&!0!==n&&(t=function(t){return l(t,o.uint8array?new Uint8Array(t.length):new Array(t.length))}(t))),t):u.Promise.reject(new Error("Can't read the data of '"+r+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"set-immediate-shim":54}],33:[function(t,e,r){"use strict";var i=t("./reader/readerFor"),n=t("./utils"),s=t("./signature"),a=t("./zipEntry"),o=(t("./utf8"),t("./support"));function h(t){this.files=[],this.loadOptions=t}h.prototype={checkSignature:function(t){if(!this.reader.readAndCheckSignature(t)){this.reader.index-=4;var e=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+n.pretty(e)+", expected "+n.pretty(t)+")")}},isSignature:function(t,e){var r=this.reader.index;this.reader.setIndex(t);var i=this.reader.readString(4)===e;return this.reader.setIndex(r),i},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var t=this.reader.readData(this.zipCommentLength),e=o.uint8array?"uint8array":"array",r=n.transformTo(e,t);this.zipComment=this.loadOptions.decodeFileName(r)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var t,e,r,i=this.zip64EndOfCentralSize-44;0<i;)t=this.reader.readInt(2),e=this.reader.readInt(4),r=this.reader.readData(e),this.zip64ExtensibleData[t]={id:t,length:e,value:r}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),1<this.disksCount)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var t,e;for(t=0;t<this.files.length;t++)e=this.files[t],this.reader.setIndex(e.localHeaderOffset),this.checkSignature(s.LOCAL_FILE_HEADER),e.readLocalPart(this.reader),e.handleUTF8(),e.processAttributes()},readCentralDir:function(){var t;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(s.CENTRAL_FILE_HEADER);)(t=new a({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(t);if(this.centralDirRecords!==this.files.length&&0!==this.centralDirRecords&&0===this.files.length)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var t=this.reader.lastIndexOfSignature(s.CENTRAL_DIRECTORY_END);if(t<0)throw!this.isSignature(0,s.LOCAL_FILE_HEADER)?new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"):new Error("Corrupted zip: can't find end of central directory");this.reader.setIndex(t);var e=t;if(this.checkSignature(s.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===n.MAX_VALUE_16BITS||this.diskWithCentralDirStart===n.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===n.MAX_VALUE_16BITS||this.centralDirRecords===n.MAX_VALUE_16BITS||this.centralDirSize===n.MAX_VALUE_32BITS||this.centralDirOffset===n.MAX_VALUE_32BITS){if(this.zip64=!0,(t=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(t),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,s.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var r=this.centralDirOffset+this.centralDirSize;this.zip64&&(r+=20,r+=12+this.zip64EndOfCentralSize);var i=e-r;if(0<i)this.isSignature(e,s.CENTRAL_FILE_HEADER)||(this.reader.zero=i);else if(i<0)throw new Error("Corrupted zip: missing "+Math.abs(i)+" bytes.")},prepareReader:function(t){this.reader=i(t)},load:function(t){this.prepareReader(t),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},e.exports=h},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(t,e,r){"use strict";var i=t("./reader/readerFor"),s=t("./utils"),n=t("./compressedObject"),a=t("./crc32"),o=t("./utf8"),h=t("./compressions"),u=t("./support");function l(t,e){this.options=t,this.loadOptions=e}l.prototype={isEncrypted:function(){return 1==(1&this.bitFlag)},useUTF8:function(){return 2048==(2048&this.bitFlag)},readLocalPart:function(t){var e,r;if(t.skip(22),this.fileNameLength=t.readInt(2),r=t.readInt(2),this.fileName=t.readData(this.fileNameLength),t.skip(r),-1===this.compressedSize||-1===this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough information from the central directory (compressedSize === -1 || uncompressedSize === -1)");if(null===(e=function(t){for(var e in h)if(h.hasOwnProperty(e)&&h[e].magic===t)return h[e];return null}(this.compressionMethod)))throw new Error("Corrupted zip : compression "+s.pretty(this.compressionMethod)+" unknown (inner file : "+s.transformTo("string",this.fileName)+")");this.decompressed=new n(this.compressedSize,this.uncompressedSize,this.crc32,e,t.readData(this.compressedSize))},readCentralPart:function(t){this.versionMadeBy=t.readInt(2),t.skip(2),this.bitFlag=t.readInt(2),this.compressionMethod=t.readString(2),this.date=t.readDate(),this.crc32=t.readInt(4),this.compressedSize=t.readInt(4),this.uncompressedSize=t.readInt(4);var e=t.readInt(2);if(this.extraFieldsLength=t.readInt(2),this.fileCommentLength=t.readInt(2),this.diskNumberStart=t.readInt(2),this.internalFileAttributes=t.readInt(2),this.externalFileAttributes=t.readInt(4),this.localHeaderOffset=t.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");t.skip(e),this.readExtraFields(t),this.parseZIP64ExtraField(t),this.fileComment=t.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var t=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),0==t&&(this.dosPermissions=63&this.externalFileAttributes),3==t&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(t){if(this.extraFields[1]){var e=i(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(t){var e,r,i,n=t.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});t.index+4<n;)e=t.readInt(2),r=t.readInt(2),i=t.readData(r),this.extraFields[e]={id:e,length:r,value:i};t.setIndex(n)},handleUTF8:function(){var t=u.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=o.utf8decode(this.fileName),this.fileCommentStr=o.utf8decode(this.fileComment);else{var e=this.findExtraFieldUnicodePath();if(null!==e)this.fileNameStr=e;else{var r=s.transformTo(t,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(r)}var i=this.findExtraFieldUnicodeComment();if(null!==i)this.fileCommentStr=i;else{var n=s.transformTo(t,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(n)}}},findExtraFieldUnicodePath:function(){var t=this.extraFields[28789];if(t){var e=i(t.value);return 1!==e.readInt(1)?null:a(this.fileName)!==e.readInt(4)?null:o.utf8decode(e.readData(t.length-5))}return null},findExtraFieldUnicodeComment:function(){var t=this.extraFields[25461];if(t){var e=i(t.value);return 1!==e.readInt(1)?null:a(this.fileComment)!==e.readInt(4)?null:o.utf8decode(e.readData(t.length-5))}return null}},e.exports=l},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(t,e,r){"use strict";function i(t,e,r){this.name=t,this.dir=r.dir,this.date=r.date,this.comment=r.comment,this.unixPermissions=r.unixPermissions,this.dosPermissions=r.dosPermissions,this._data=e,this._dataBinary=r.binary,this.options={compression:r.compression,compressionOptions:r.compressionOptions}}var s=t("./stream/StreamHelper"),n=t("./stream/DataWorker"),a=t("./utf8"),o=t("./compressedObject"),h=t("./stream/GenericWorker");i.prototype={internalStream:function(t){var e=null,r="string";try{if(!t)throw new Error("No output type specified.");var i="string"===(r=t.toLowerCase())||"text"===r;"binarystring"!==r&&"text"!==r||(r="string"),e=this._decompressWorker();var n=!this._dataBinary;n&&!i&&(e=e.pipe(new a.Utf8EncodeWorker)),!n&&i&&(e=e.pipe(new a.Utf8DecodeWorker))}catch(t){(e=new h("error")).error(t)}return new s(e,r,"")},async:function(t,e){return this.internalStream(t).accumulate(e)},nodeStream:function(t,e){return this.internalStream(t||"nodebuffer").toNodejsStream(e)},_compressWorker:function(t,e){if(this._data instanceof o&&this._data.compression.magic===t.magic)return this._data.getCompressedWorker();var r=this._decompressWorker();return this._dataBinary||(r=r.pipe(new a.Utf8EncodeWorker)),o.createWorkerFrom(r,t,e)},_decompressWorker:function(){return this._data instanceof o?this._data.getContentWorker():this._data instanceof h?this._data:new n(this._data)}};for(var u=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],l=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},f=0;f<u.length;f++)i.prototype[u[f]]=l;e.exports=i},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(t,l,e){(function(e){"use strict";var r,i,t=e.MutationObserver||e.WebKitMutationObserver;if(t){var n=0,s=new t(u),a=e.document.createTextNode("");s.observe(a,{characterData:!0}),r=function(){a.data=n=++n%2}}else if(e.setImmediate||void 0===e.MessageChannel)r="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var t=e.document.createElement("script");t.onreadystatechange=function(){u(),t.onreadystatechange=null,t.parentNode.removeChild(t),t=null},e.document.documentElement.appendChild(t)}:function(){setTimeout(u,0)};else{var o=new e.MessageChannel;o.port1.onmessage=u,r=function(){o.port2.postMessage(0)}}var h=[];function u(){var t,e;i=!0;for(var r=h.length;r;){for(e=h,h=[],t=-1;++t<r;)e[t]();r=h.length}i=!1}l.exports=function(t){1!==h.push(t)||i||r()}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],37:[function(t,e,r){"use strict";var n=t("immediate");function u(){}var l={},s=["REJECTED"],a=["FULFILLED"],i=["PENDING"];function o(t){if("function"!=typeof t)throw new TypeError("resolver must be a function");this.state=i,this.queue=[],this.outcome=void 0,t!==u&&c(this,t)}function h(t,e,r){this.promise=t,"function"==typeof e&&(this.onFulfilled=e,this.callFulfilled=this.otherCallFulfilled),"function"==typeof r&&(this.onRejected=r,this.callRejected=this.otherCallRejected)}function f(e,r,i){n(function(){var t;try{t=r(i)}catch(t){return l.reject(e,t)}t===e?l.reject(e,new TypeError("Cannot resolve promise with itself")):l.resolve(e,t)})}function d(t){var e=t&&t.then;if(t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof e)return function(){e.apply(t,arguments)}}function c(e,t){var r=!1;function i(t){r||(r=!0,l.reject(e,t))}function n(t){r||(r=!0,l.resolve(e,t))}var s=p(function(){t(n,i)});"error"===s.status&&i(s.value)}function p(t,e){var r={};try{r.value=t(e),r.status="success"}catch(t){r.status="error",r.value=t}return r}(e.exports=o).prototype.finally=function(e){if("function"!=typeof e)return this;var r=this.constructor;return this.then(function(t){return r.resolve(e()).then(function(){return t})},function(t){return r.resolve(e()).then(function(){throw t})})},o.prototype.catch=function(t){return this.then(null,t)},o.prototype.then=function(t,e){if("function"!=typeof t&&this.state===a||"function"!=typeof e&&this.state===s)return this;var r=new this.constructor(u);this.state!==i?f(r,this.state===a?t:e,this.outcome):this.queue.push(new h(r,t,e));return r},h.prototype.callFulfilled=function(t){l.resolve(this.promise,t)},h.prototype.otherCallFulfilled=function(t){f(this.promise,this.onFulfilled,t)},h.prototype.callRejected=function(t){l.reject(this.promise,t)},h.prototype.otherCallRejected=function(t){f(this.promise,this.onRejected,t)},l.resolve=function(t,e){var r=p(d,e);if("error"===r.status)return l.reject(t,r.value);var i=r.value;if(i)c(t,i);else{t.state=a,t.outcome=e;for(var n=-1,s=t.queue.length;++n<s;)t.queue[n].callFulfilled(e)}return t},l.reject=function(t,e){t.state=s,t.outcome=e;for(var r=-1,i=t.queue.length;++r<i;)t.queue[r].callRejected(e);return t},o.resolve=function(t){if(t instanceof this)return t;return l.resolve(new this(u),t)},o.reject=function(t){var e=new this(u);return l.reject(e,t)},o.all=function(t){var r=this;if("[object Array]"!==Object.prototype.toString.call(t))return this.reject(new TypeError("must be an array"));var i=t.length,n=!1;if(!i)return this.resolve([]);var s=new Array(i),a=0,e=-1,o=new this(u);for(;++e<i;)h(t[e],e);return o;function h(t,e){r.resolve(t).then(function(t){s[e]=t,++a!==i||n||(n=!0,l.resolve(o,s))},function(t){n||(n=!0,l.reject(o,t))})}},o.race=function(t){var e=this;if("[object Array]"!==Object.prototype.toString.call(t))return this.reject(new TypeError("must be an array"));var r=t.length,i=!1;if(!r)return this.resolve([]);var n=-1,s=new this(u);for(;++n<r;)a=t[n],e.resolve(a).then(function(t){i||(i=!0,l.resolve(s,t))},function(t){i||(i=!0,l.reject(s,t))});var a;return s}},{immediate:36}],38:[function(t,e,r){"use strict";var i={};(0,t("./lib/utils/common").assign)(i,t("./lib/deflate"),t("./lib/inflate"),t("./lib/zlib/constants")),e.exports=i},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(t,e,r){"use strict";var a=t("./zlib/deflate"),o=t("./utils/common"),h=t("./utils/strings"),n=t("./zlib/messages"),s=t("./zlib/zstream"),u=Object.prototype.toString,l=0,f=-1,d=0,c=8;function p(t){if(!(this instanceof p))return new p(t);this.options=o.assign({level:f,method:c,chunkSize:16384,windowBits:15,memLevel:8,strategy:d,to:""},t||{});var e=this.options;e.raw&&0<e.windowBits?e.windowBits=-e.windowBits:e.gzip&&0<e.windowBits&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=a.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(r!==l)throw new Error(n[r]);if(e.header&&a.deflateSetHeader(this.strm,e.header),e.dictionary){var i;if(i="string"==typeof e.dictionary?h.string2buf(e.dictionary):"[object ArrayBuffer]"===u.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(r=a.deflateSetDictionary(this.strm,i))!==l)throw new Error(n[r]);this._dict_set=!0}}function i(t,e){var r=new p(e);if(r.push(t,!0),r.err)throw r.msg||n[r.err];return r.result}p.prototype.push=function(t,e){var r,i,n=this.strm,s=this.options.chunkSize;if(this.ended)return!1;i=e===~~e?e:!0===e?4:0,"string"==typeof t?n.input=h.string2buf(t):"[object ArrayBuffer]"===u.call(t)?n.input=new Uint8Array(t):n.input=t,n.next_in=0,n.avail_in=n.input.length;do{if(0===n.avail_out&&(n.output=new o.Buf8(s),n.next_out=0,n.avail_out=s),1!==(r=a.deflate(n,i))&&r!==l)return this.onEnd(r),!(this.ended=!0);0!==n.avail_out&&(0!==n.avail_in||4!==i&&2!==i)||("string"===this.options.to?this.onData(h.buf2binstring(o.shrinkBuf(n.output,n.next_out))):this.onData(o.shrinkBuf(n.output,n.next_out)))}while((0<n.avail_in||0===n.avail_out)&&1!==r);return 4===i?(r=a.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===l):2!==i||(this.onEnd(l),!(n.avail_out=0))},p.prototype.onData=function(t){this.chunks.push(t)},p.prototype.onEnd=function(t){t===l&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},r.Deflate=p,r.deflate=i,r.deflateRaw=function(t,e){return(e=e||{}).raw=!0,i(t,e)},r.gzip=function(t,e){return(e=e||{}).gzip=!0,i(t,e)}},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(t,e,r){"use strict";var d=t("./zlib/inflate"),c=t("./utils/common"),p=t("./utils/strings"),m=t("./zlib/constants"),i=t("./zlib/messages"),n=t("./zlib/zstream"),s=t("./zlib/gzheader"),_=Object.prototype.toString;function a(t){if(!(this instanceof a))return new a(t);this.options=c.assign({chunkSize:16384,windowBits:0,to:""},t||{});var e=this.options;e.raw&&0<=e.windowBits&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(0<=e.windowBits&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),15<e.windowBits&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new n,this.strm.avail_out=0;var r=d.inflateInit2(this.strm,e.windowBits);if(r!==m.Z_OK)throw new Error(i[r]);this.header=new s,d.inflateGetHeader(this.strm,this.header)}function o(t,e){var r=new a(e);if(r.push(t,!0),r.err)throw r.msg||i[r.err];return r.result}a.prototype.push=function(t,e){var r,i,n,s,a,o,h=this.strm,u=this.options.chunkSize,l=this.options.dictionary,f=!1;if(this.ended)return!1;i=e===~~e?e:!0===e?m.Z_FINISH:m.Z_NO_FLUSH,"string"==typeof t?h.input=p.binstring2buf(t):"[object ArrayBuffer]"===_.call(t)?h.input=new Uint8Array(t):h.input=t,h.next_in=0,h.avail_in=h.input.length;do{if(0===h.avail_out&&(h.output=new c.Buf8(u),h.next_out=0,h.avail_out=u),(r=d.inflate(h,m.Z_NO_FLUSH))===m.Z_NEED_DICT&&l&&(o="string"==typeof l?p.string2buf(l):"[object ArrayBuffer]"===_.call(l)?new Uint8Array(l):l,r=d.inflateSetDictionary(this.strm,o)),r===m.Z_BUF_ERROR&&!0===f&&(r=m.Z_OK,f=!1),r!==m.Z_STREAM_END&&r!==m.Z_OK)return this.onEnd(r),!(this.ended=!0);h.next_out&&(0!==h.avail_out&&r!==m.Z_STREAM_END&&(0!==h.avail_in||i!==m.Z_FINISH&&i!==m.Z_SYNC_FLUSH)||("string"===this.options.to?(n=p.utf8border(h.output,h.next_out),s=h.next_out-n,a=p.buf2string(h.output,n),h.next_out=s,h.avail_out=u-s,s&&c.arraySet(h.output,h.output,n,s,0),this.onData(a)):this.onData(c.shrinkBuf(h.output,h.next_out)))),0===h.avail_in&&0===h.avail_out&&(f=!0)}while((0<h.avail_in||0===h.avail_out)&&r!==m.Z_STREAM_END);return r===m.Z_STREAM_END&&(i=m.Z_FINISH),i===m.Z_FINISH?(r=d.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===m.Z_OK):i!==m.Z_SYNC_FLUSH||(this.onEnd(m.Z_OK),!(h.avail_out=0))},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===m.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=c.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},r.Inflate=a,r.inflate=o,r.inflateRaw=function(t,e){return(e=e||{}).raw=!0,o(t,e)},r.ungzip=o},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(t,e,r){"use strict";var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;r.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var r=e.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)r.hasOwnProperty(i)&&(t[i]=r[i])}}return t},r.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var n={arraySet:function(t,e,r,i,n){if(e.subarray&&t.subarray)t.set(e.subarray(r,r+i),n);else for(var s=0;s<i;s++)t[n+s]=e[r+s]},flattenChunks:function(t){var e,r,i,n,s,a;for(e=i=0,r=t.length;e<r;e++)i+=t[e].length;for(a=new Uint8Array(i),e=n=0,r=t.length;e<r;e++)s=t[e],a.set(s,n),n+=s.length;return a}},s={arraySet:function(t,e,r,i,n){for(var s=0;s<i;s++)t[n+s]=e[r+s]},flattenChunks:function(t){return[].concat.apply([],t)}};r.setTyped=function(t){t?(r.Buf8=Uint8Array,r.Buf16=Uint16Array,r.Buf32=Int32Array,r.assign(r,n)):(r.Buf8=Array,r.Buf16=Array,r.Buf32=Array,r.assign(r,s))},r.setTyped(i)},{}],42:[function(t,e,r){"use strict";var h=t("./common"),n=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){n=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var u=new h.Buf8(256),i=0;i<256;i++)u[i]=252<=i?6:248<=i?5:240<=i?4:224<=i?3:192<=i?2:1;function l(t,e){if(e<65537&&(t.subarray&&s||!t.subarray&&n))return String.fromCharCode.apply(null,h.shrinkBuf(t,e));for(var r="",i=0;i<e;i++)r+=String.fromCharCode(t[i]);return r}u[254]=u[254]=1,r.string2buf=function(t){var e,r,i,n,s,a=t.length,o=0;for(n=0;n<a;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),o+=r<128?1:r<2048?2:r<65536?3:4;for(e=new h.Buf8(o),n=s=0;s<o;n++)55296==(64512&(r=t.charCodeAt(n)))&&n+1<a&&56320==(64512&(i=t.charCodeAt(n+1)))&&(r=65536+(r-55296<<10)+(i-56320),n++),r<128?e[s++]=r:(r<2048?e[s++]=192|r>>>6:(r<65536?e[s++]=224|r>>>12:(e[s++]=240|r>>>18,e[s++]=128|r>>>12&63),e[s++]=128|r>>>6&63),e[s++]=128|63&r);return e},r.buf2binstring=function(t){return l(t,t.length)},r.binstring2buf=function(t){for(var e=new h.Buf8(t.length),r=0,i=e.length;r<i;r++)e[r]=t.charCodeAt(r);return e},r.buf2string=function(t,e){var r,i,n,s,a=e||t.length,o=new Array(2*a);for(r=i=0;r<a;)if((n=t[r++])<128)o[i++]=n;else if(4<(s=u[n]))o[i++]=65533,r+=s-1;else{for(n&=2===s?31:3===s?15:7;1<s&&r<a;)n=n<<6|63&t[r++],s--;1<s?o[i++]=65533:n<65536?o[i++]=n:(n-=65536,o[i++]=55296|n>>10&1023,o[i++]=56320|1023&n)}return l(o,i)},r.utf8border=function(t,e){var r;for((e=e||t.length)>t.length&&(e=t.length),r=e-1;0<=r&&128==(192&t[r]);)r--;return r<0?e:0===r?e:r+u[t[r]]>e?r:e}},{"./common":41}],43:[function(t,e,r){"use strict";e.exports=function(t,e,r,i){for(var n=65535&t|0,s=t>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3<r?2e3:r;s=s+(n=n+e[i++]|0)|0,--a;);n%=65521,s%=65521}return n|s<<16|0}},{}],44:[function(t,e,r){"use strict";e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],45:[function(t,e,r){"use strict";var o=function(){for(var t,e=[],r=0;r<256;r++){t=r;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[r]=t}return e}();e.exports=function(t,e,r,i){var n=o,s=i+r;t^=-1;for(var a=i;a<s;a++)t=t>>>8^n[255&(t^e[a])];return-1^t}},{}],46:[function(t,e,r){"use strict";var h,d=t("../utils/common"),u=t("./trees"),c=t("./adler32"),p=t("./crc32"),i=t("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,n=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(t,e){return t.msg=i[e],e}function T(t){return(t<<1)-(4<t?9:0)}function D(t){for(var e=t.length;0<=--e;)t[e]=0}function F(t){var e=t.state,r=e.pending;r>t.avail_out&&(r=t.avail_out),0!==r&&(d.arraySet(t.output,e.pending_buf,e.pending_out,r,t.next_out),t.next_out+=r,e.pending_out+=r,t.total_out+=r,t.avail_out-=r,e.pending-=r,0===e.pending&&(e.pending_out=0))}function N(t,e){u._tr_flush_block(t,0<=t.block_start?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,F(t.strm)}function U(t,e){t.pending_buf[t.pending++]=e}function P(t,e){t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e}function L(t,e){var r,i,n=t.max_chain_length,s=t.strstart,a=t.prev_length,o=t.nice_match,h=t.strstart>t.w_size-z?t.strstart-(t.w_size-z):0,u=t.window,l=t.w_mask,f=t.prev,d=t.strstart+S,c=u[s+a-1],p=u[s+a];t.prev_length>=t.good_match&&(n>>=2),o>t.lookahead&&(o=t.lookahead);do{if(u[(r=e)+a]===p&&u[r+a-1]===c&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&s<d);if(i=S-(d-s),s=d-S,a<i){if(t.match_start=e,o<=(a=i))break;c=u[s+a-1],p=u[s+a]}}}while((e=f[e&l])>h&&0!=--n);return a<=t.lookahead?a:t.lookahead}function j(t){var e,r,i,n,s,a,o,h,u,l,f=t.w_size;do{if(n=t.window_size-t.lookahead-t.strstart,t.strstart>=f+(f-z)){for(d.arraySet(t.window,t.window,f,f,0),t.match_start-=f,t.strstart-=f,t.block_start-=f,e=r=t.hash_size;i=t.head[--e],t.head[e]=f<=i?i-f:0,--r;);for(e=r=f;i=t.prev[--e],t.prev[e]=f<=i?i-f:0,--r;);n+=f}if(0===t.strm.avail_in)break;if(a=t.strm,o=t.window,h=t.strstart+t.lookahead,u=n,l=void 0,l=a.avail_in,u<l&&(l=u),r=0===l?0:(a.avail_in-=l,d.arraySet(o,a.input,a.next_in,l,h),1===a.state.wrap?a.adler=c(a.adler,o,l,h):2===a.state.wrap&&(a.adler=p(a.adler,o,l,h)),a.next_in+=l,a.total_in+=l,l),t.lookahead+=r,t.lookahead+t.insert>=x)for(s=t.strstart-t.insert,t.ins_h=t.window[s],t.ins_h=(t.ins_h<<t.hash_shift^t.window[s+1])&t.hash_mask;t.insert&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[s+x-1])&t.hash_mask,t.prev[s&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=s,s++,t.insert--,!(t.lookahead+t.insert<x)););}while(t.lookahead<z&&0!==t.strm.avail_in)}function Z(t,e){for(var r,i;;){if(t.lookahead<z){if(j(t),t.lookahead<z&&e===l)return A;if(0===t.lookahead)break}if(r=0,t.lookahead>=x&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==r&&t.strstart-r<=t.w_size-z&&(t.match_length=L(t,r)),t.match_length>=x)if(i=u._tr_tally(t,t.strstart-t.match_start,t.match_length-x),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=x){for(t.match_length--;t.strstart++,t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart,0!=--t.match_length;);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+1])&t.hash_mask;else i=u._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=t.strstart<x-1?t.strstart:x-1,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}function W(t,e){for(var r,i,n;;){if(t.lookahead<z){if(j(t),t.lookahead<z&&e===l)return A;if(0===t.lookahead)break}if(r=0,t.lookahead>=x&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=x-1,0!==r&&t.prev_length<t.max_lazy_match&&t.strstart-r<=t.w_size-z&&(t.match_length=L(t,r),t.match_length<=5&&(1===t.strategy||t.match_length===x&&4096<t.strstart-t.match_start)&&(t.match_length=x-1)),t.prev_length>=x&&t.match_length<=t.prev_length){for(n=t.strstart+t.lookahead-x,i=u._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-x),t.lookahead-=t.prev_length-1,t.prev_length-=2;++t.strstart<=n&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+x-1])&t.hash_mask,r=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!=--t.prev_length;);if(t.match_available=0,t.match_length=x-1,t.strstart++,i&&(N(t,!1),0===t.strm.avail_out))return A}else if(t.match_available){if((i=u._tr_tally(t,0,t.window[t.strstart-1]))&&N(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return A}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=u._tr_tally(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<x-1?t.strstart:x-1,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}function M(t,e,r,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=r,this.max_chain=i,this.func=n}function H(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=v,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new d.Buf16(2*w),this.dyn_dtree=new d.Buf16(2*(2*a+1)),this.bl_tree=new d.Buf16(2*(2*o+1)),D(this.dyn_ltree),D(this.dyn_dtree),D(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new d.Buf16(k+1),this.heap=new d.Buf16(2*s+1),D(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new d.Buf16(2*s+1),D(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function G(t){var e;return t&&t.state?(t.total_in=t.total_out=0,t.data_type=n,(e=t.state).pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?C:E,t.adler=2===e.wrap?0:1,e.last_flush=l,u._tr_init(e),m):R(t,_)}function K(t){var e=G(t);return e===m&&function(t){t.window_size=2*t.w_size,D(t.head),t.max_lazy_match=h[t.level].max_lazy,t.good_match=h[t.level].good_length,t.nice_match=h[t.level].nice_length,t.max_chain_length=h[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=x-1,t.match_available=0,t.ins_h=0}(t.state),e}function Y(t,e,r,i,n,s){if(!t)return _;var a=1;if(e===g&&(e=6),i<0?(a=0,i=-i):15<i&&(a=2,i-=16),n<1||y<n||r!==v||i<8||15<i||e<0||9<e||s<0||b<s)return R(t,_);8===i&&(i=9);var o=new H;return(t.state=o).strm=t,o.wrap=a,o.gzhead=null,o.w_bits=i,o.w_size=1<<o.w_bits,o.w_mask=o.w_size-1,o.hash_bits=n+7,o.hash_size=1<<o.hash_bits,o.hash_mask=o.hash_size-1,o.hash_shift=~~((o.hash_bits+x-1)/x),o.window=new d.Buf8(2*o.w_size),o.head=new d.Buf16(o.hash_size),o.prev=new d.Buf16(o.w_size),o.lit_bufsize=1<<n+6,o.pending_buf_size=4*o.lit_bufsize,o.pending_buf=new d.Buf8(o.pending_buf_size),o.d_buf=1*o.lit_bufsize,o.l_buf=3*o.lit_bufsize,o.level=e,o.strategy=s,o.method=r,K(t)}h=[new M(0,0,0,0,function(t,e){var r=65535;for(r>t.pending_buf_size-5&&(r=t.pending_buf_size-5);;){if(t.lookahead<=1){if(j(t),0===t.lookahead&&e===l)return A;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var i=t.block_start+r;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,N(t,!1),0===t.strm.avail_out))return A;if(t.strstart-t.block_start>=t.w_size-z&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=0,e===f?(N(t,!0),0===t.strm.avail_out?O:B):(t.strstart>t.block_start&&(N(t,!1),t.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(t,e){return Y(t,e,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(t,e){return t&&t.state?2!==t.state.wrap?_:(t.state.gzhead=e,m):_},r.deflate=function(t,e){var r,i,n,s;if(!t||!t.state||5<e||e<0)return t?R(t,_):_;if(i=t.state,!t.output||!t.input&&0!==t.avail_in||666===i.status&&e!==f)return R(t,0===t.avail_out?-5:_);if(i.strm=t,r=i.last_flush,i.last_flush=e,i.status===C)if(2===i.wrap)t.adler=0,U(i,31),U(i,139),U(i,8),i.gzhead?(U(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),U(i,255&i.gzhead.time),U(i,i.gzhead.time>>8&255),U(i,i.gzhead.time>>16&255),U(i,i.gzhead.time>>24&255),U(i,9===i.level?2:2<=i.strategy||i.level<2?4:0),U(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(U(i,255&i.gzhead.extra.length),U(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(t.adler=p(t.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69):(U(i,0),U(i,0),U(i,0),U(i,0),U(i,0),U(i,9===i.level?2:2<=i.strategy||i.level<2?4:0),U(i,3),i.status=E);else{var a=v+(i.w_bits-8<<4)<<8;a|=(2<=i.strategy||i.level<2?0:i.level<6?1:6===i.level?2:3)<<6,0!==i.strstart&&(a|=32),a+=31-a%31,i.status=E,P(i,a),0!==i.strstart&&(P(i,t.adler>>>16),P(i,65535&t.adler)),t.adler=1}if(69===i.status)if(i.gzhead.extra){for(n=i.pending;i.gzindex<(65535&i.gzhead.extra.length)&&(i.pending!==i.pending_buf_size||(i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),F(t),n=i.pending,i.pending!==i.pending_buf_size));)U(i,255&i.gzhead.extra[i.gzindex]),i.gzindex++;i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),i.gzindex===i.gzhead.extra.length&&(i.gzindex=0,i.status=73)}else i.status=73;if(73===i.status)if(i.gzhead.name){n=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),F(t),n=i.pending,i.pending===i.pending_buf_size)){s=1;break}s=i.gzindex<i.gzhead.name.length?255&i.gzhead.name.charCodeAt(i.gzindex++):0,U(i,s)}while(0!==s);i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),0===s&&(i.gzindex=0,i.status=91)}else i.status=91;if(91===i.status)if(i.gzhead.comment){n=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),F(t),n=i.pending,i.pending===i.pending_buf_size)){s=1;break}s=i.gzindex<i.gzhead.comment.length?255&i.gzhead.comment.charCodeAt(i.gzindex++):0,U(i,s)}while(0!==s);i.gzhead.hcrc&&i.pending>n&&(t.adler=p(t.adler,i.pending_buf,i.pending-n,n)),0===s&&(i.status=103)}else i.status=103;if(103===i.status&&(i.gzhead.hcrc?(i.pending+2>i.pending_buf_size&&F(t),i.pending+2<=i.pending_buf_size&&(U(i,255&t.adler),U(i,t.adler>>8&255),t.adler=0,i.status=E)):i.status=E),0!==i.pending){if(F(t),0===t.avail_out)return i.last_flush=-1,m}else if(0===t.avail_in&&T(e)<=T(r)&&e!==f)return R(t,-5);if(666===i.status&&0!==t.avail_in)return R(t,-5);if(0!==t.avail_in||0!==i.lookahead||e!==l&&666!==i.status){var o=2===i.strategy?function(t,e){for(var r;;){if(0===t.lookahead&&(j(t),0===t.lookahead)){if(e===l)return A;break}if(t.match_length=0,r=u._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,r&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=0,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}(i,e):3===i.strategy?function(t,e){for(var r,i,n,s,a=t.window;;){if(t.lookahead<=S){if(j(t),t.lookahead<=S&&e===l)return A;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=x&&0<t.strstart&&(i=a[n=t.strstart-1])===a[++n]&&i===a[++n]&&i===a[++n]){s=t.strstart+S;do{}while(i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&i===a[++n]&&n<s);t.match_length=S-(s-n),t.match_length>t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=x?(r=u._tr_tally(t,1,t.match_length-x),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(r=u._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),r&&(N(t,!1),0===t.strm.avail_out))return A}return t.insert=0,e===f?(N(t,!0),0===t.strm.avail_out?O:B):t.last_lit&&(N(t,!1),0===t.strm.avail_out)?A:I}(i,e):h[i.level].func(i,e);if(o!==O&&o!==B||(i.status=666),o===A||o===O)return 0===t.avail_out&&(i.last_flush=-1),m;if(o===I&&(1===e?u._tr_align(i):5!==e&&(u._tr_stored_block(i,0,0,!1),3===e&&(D(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),F(t),0===t.avail_out))return i.last_flush=-1,m}return e!==f?m:i.wrap<=0?1:(2===i.wrap?(U(i,255&t.adler),U(i,t.adler>>8&255),U(i,t.adler>>16&255),U(i,t.adler>>24&255),U(i,255&t.total_in),U(i,t.total_in>>8&255),U(i,t.total_in>>16&255),U(i,t.total_in>>24&255)):(P(i,t.adler>>>16),P(i,65535&t.adler)),F(t),0<i.wrap&&(i.wrap=-i.wrap),0!==i.pending?m:1)},r.deflateEnd=function(t){var e;return t&&t.state?(e=t.state.status)!==C&&69!==e&&73!==e&&91!==e&&103!==e&&e!==E&&666!==e?R(t,_):(t.state=null,e===E?R(t,-3):m):_},r.deflateSetDictionary=function(t,e){var r,i,n,s,a,o,h,u,l=e.length;if(!t||!t.state)return _;if(2===(s=(r=t.state).wrap)||1===s&&r.status!==C||r.lookahead)return _;for(1===s&&(t.adler=c(t.adler,e,l,0)),r.wrap=0,l>=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new d.Buf8(r.w_size),d.arraySet(u,e,l-r.w_size,r.w_size,0),e=u,l=r.w_size),a=t.avail_in,o=t.next_in,h=t.input,t.avail_in=l,t.next_in=0,t.input=e,j(r);r.lookahead>=x;){for(i=r.strstart,n=r.lookahead-(x-1);r.ins_h=(r.ins_h<<r.hash_shift^r.window[i+x-1])&r.hash_mask,r.prev[i&r.w_mask]=r.head[r.ins_h],r.head[r.ins_h]=i,i++,--n;);r.strstart=i,r.lookahead=x-1,j(r)}return r.strstart+=r.lookahead,r.block_start=r.strstart,r.insert=r.lookahead,r.lookahead=0,r.match_length=r.prev_length=x-1,r.match_available=0,t.next_in=o,t.input=h,t.avail_in=a,r.wrap=s,m},r.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(t,e,r){"use strict";e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],48:[function(t,e,r){"use strict";e.exports=function(t,e){var r,i,n,s,a,o,h,u,l,f,d,c,p,m,_,g,b,v,y,w,k,x,S,z,C;r=t.state,i=t.next_in,z=t.input,n=i+(t.avail_in-5),s=t.next_out,C=t.output,a=s-(e-t.avail_out),o=s+(t.avail_out-257),h=r.dmax,u=r.wsize,l=r.whave,f=r.wnext,d=r.window,c=r.hold,p=r.bits,m=r.lencode,_=r.distcode,g=(1<<r.lenbits)-1,b=(1<<r.distbits)-1;t:do{p<15&&(c+=z[i++]<<p,p+=8,c+=z[i++]<<p,p+=8),v=m[c&g];e:for(;;){if(c>>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(c&(1<<y)-1)];continue e}if(32&y){r.mode=12;break t}t.msg="invalid literal/length code",r.mode=30;break t}w=65535&v,(y&=15)&&(p<y&&(c+=z[i++]<<p,p+=8),w+=c&(1<<y)-1,c>>>=y,p-=y),p<15&&(c+=z[i++]<<p,p+=8,c+=z[i++]<<p,p+=8),v=_[c&b];r:for(;;){if(c>>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(c&(1<<y)-1)];continue r}t.msg="invalid distance code",r.mode=30;break t}if(k=65535&v,p<(y&=15)&&(c+=z[i++]<<p,(p+=8)<y&&(c+=z[i++]<<p,p+=8)),h<(k+=c&(1<<y)-1)){t.msg="invalid distance too far back",r.mode=30;break t}if(c>>>=y,p-=y,(y=s-a)<k){if(l<(y=k-y)&&r.sane){t.msg="invalid distance too far back",r.mode=30;break t}if(S=d,(x=0)===f){if(x+=u-y,y<w){for(w-=y;C[s++]=d[x++],--y;);x=s-k,S=C}}else if(f<y){if(x+=u+f-y,(y-=f)<w){for(w-=y;C[s++]=d[x++],--y;);if(x=0,f<w){for(w-=y=f;C[s++]=d[x++],--y;);x=s-k,S=C}}}else if(x+=f-y,y<w){for(w-=y;C[s++]=d[x++],--y;);x=s-k,S=C}for(;2<w;)C[s++]=S[x++],C[s++]=S[x++],C[s++]=S[x++],w-=3;w&&(C[s++]=S[x++],1<w&&(C[s++]=S[x++]))}else{for(x=s-k;C[s++]=C[x++],C[s++]=C[x++],C[s++]=C[x++],2<(w-=3););w&&(C[s++]=C[x++],1<w&&(C[s++]=C[x++]))}break}}break}}while(i<n&&s<o);i-=w=p>>3,c&=(1<<(p-=w<<3))-1,t.next_in=i,t.next_out=s,t.avail_in=i<n?n-i+5:5-(i-n),t.avail_out=s<o?o-s+257:257-(s-o),r.hold=c,r.bits=p}},{}],49:[function(t,e,r){"use strict";var I=t("../utils/common"),O=t("./adler32"),B=t("./crc32"),R=t("./inffast"),T=t("./inftrees"),D=1,F=2,N=0,U=-2,P=1,i=852,n=592;function L(t){return(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=P,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new I.Buf32(i),e.distcode=e.distdyn=new I.Buf32(n),e.sane=1,e.back=-1,N):U}function o(t){var e;return t&&t.state?((e=t.state).wsize=0,e.whave=0,e.wnext=0,a(t)):U}function h(t,e){var r,i;return t&&t.state?(i=t.state,e<0?(r=0,e=-e):(r=1+(e>>4),e<48&&(e&=15)),e&&(e<8||15<e)?U:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=r,i.wbits=e,o(t))):U}function u(t,e){var r,i;return t?(i=new s,(t.state=i).window=null,(r=h(t,e))!==N&&(t.state=null),r):U}var l,f,d=!0;function j(t){if(d){var e;for(l=new I.Buf32(512),f=new I.Buf32(32),e=0;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(T(D,t.lens,0,288,l,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;T(F,t.lens,0,32,f,0,t.work,{bits:5}),d=!1}t.lencode=l,t.lenbits=9,t.distcode=f,t.distbits=5}function Z(t,e,r,i){var n,s=t.state;return null===s.window&&(s.wsize=1<<s.wbits,s.wnext=0,s.whave=0,s.window=new I.Buf8(s.wsize)),i>=s.wsize?(I.arraySet(s.window,e,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(i<(n=s.wsize-s.wnext)&&(n=i),I.arraySet(s.window,e,r-i,n,s.wnext),(i-=n)?(I.arraySet(s.window,e,r-i,i,0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whave<s.wsize&&(s.whave+=n))),0}r.inflateReset=o,r.inflateReset2=h,r.inflateResetKeep=a,r.inflateInit=function(t){return u(t,15)},r.inflateInit2=u,r.inflate=function(t,e){var r,i,n,s,a,o,h,u,l,f,d,c,p,m,_,g,b,v,y,w,k,x,S,z,C=0,E=new I.Buf8(4),A=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return U;12===(r=t.state).mode&&(r.mode=13),a=t.next_out,n=t.output,h=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,u=r.hold,l=r.bits,f=o,d=h,x=N;t:for(;;)switch(r.mode){case P:if(0===r.wrap){r.mode=13;break}for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(2&r.wrap&&35615===u){E[r.check=0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){t.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){t.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){t.msg="invalid window size",r.mode=30;break}r.dmax=1<<k,t.adler=r.check=1,r.mode=512&u?10:12,l=u=0;break;case 2:for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(r.flags=u,8!=(255&r.flags)){t.msg="unknown compression method",r.mode=30;break}if(57344&r.flags){t.msg="unknown header flags set",r.mode=30;break}r.head&&(r.head.text=u>>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.head&&(r.head.time=u),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.head&&(r.head.xflags=255&u,r.head.os=u>>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.length=u,r.head&&(r.head.extra_len=u),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(c=r.length)&&(c=o),c&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,i,s,c,k)),512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,r.length-=c),r.length))break t;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break t;for(c=0;k=i[s+c++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&c<o;);if(512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,k)break t}else r.head&&(r.head.name=null);r.length=0,r.mode=8;case 8:if(4096&r.flags){if(0===o)break t;for(c=0;k=i[s+c++],r.head&&k&&r.length<65536&&(r.head.comment+=String.fromCharCode(k)),k&&c<o;);if(512&r.flags&&(r.check=B(r.check,i,c,s)),o-=c,s+=c,k)break t}else r.head&&(r.head.comment=null);r.mode=9;case 9:if(512&r.flags){for(;l<16;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(u!==(65535&r.check)){t.msg="header crc mismatch",r.mode=30;break}l=u=0}r.head&&(r.head.hcrc=r.flags>>9&1,r.head.done=!0),t.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}t.adler=r.check=L(u),l=u=0,r.mode=11;case 11:if(0===r.havedict)return t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,2;t.adler=r.check=1,r.mode=12;case 12:if(5===e||6===e)break t;case 13:if(r.last){u>>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}switch(r.last=1&u,l-=1,3&(u>>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==e)break;u>>>=2,l-=2;break t;case 2:r.mode=17;break;case 3:t.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if((65535&u)!=(u>>>16^65535)){t.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===e)break t;case 15:r.mode=16;case 16:if(c=r.length){if(o<c&&(c=o),h<c&&(c=h),0===c)break t;I.arraySet(n,i,s,c,a),o-=c,s+=c,h-=c,a+=c,r.length-=c;break}r.mode=12;break;case 17:for(;l<14;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(r.nlen=257+(31&u),u>>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286<r.nlen||30<r.ndist){t.msg="too many length or distance symbols",r.mode=30;break}r.have=0,r.mode=18;case 18:for(;r.have<r.ncode;){for(;l<3;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.lens[A[r.have++]]=7&u,u>>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){t.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have<r.nlen+r.ndist;){for(;g=(C=r.lencode[u&(1<<r.lenbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(b<16)u>>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(u>>>=_,l-=_,0===r.have){t.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],c=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}l-=_,k=0,c=3+(7&(u>>>=_)),u>>>=3,l-=3}else{for(z=_+7;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}l-=_,k=0,c=11+(127&(u>>>=_)),u>>>=7,l-=7}if(r.have+c>r.nlen+r.ndist){t.msg="invalid bit length repeat",r.mode=30;break}for(;c--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){t.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){t.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){t.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===e)break t;case 20:r.mode=21;case 21:if(6<=o&&258<=h){t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,R(t,d),a=t.next_out,n=t.output,h=t.avail_out,s=t.next_in,i=t.input,o=t.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<<r.lenbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(g&&0==(240&g)){for(v=_,y=g,w=b;g=(C=r.lencode[w+((u&(1<<v+y)-1)>>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}u>>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){t.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.length+=u&(1<<r.extra)-1,u>>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<<r.distbits)-1])>>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(0==(240&g)){for(v=_,y=g,w=b;g=(C=r.distcode[w+((u&(1<<v+y)-1)>>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}u>>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){t.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l<z;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}r.offset+=u&(1<<r.extra)-1,u>>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){t.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break t;if(c=d-h,r.offset>c){if((c=r.offset-c)>r.whave&&r.sane){t.msg="invalid distance too far back",r.mode=30;break}p=c>r.wnext?(c-=r.wnext,r.wsize-c):r.wnext-c,c>r.length&&(c=r.length),m=r.window}else m=n,p=a-r.offset,c=r.length;for(h<c&&(c=h),h-=c,r.length-=c;n[a++]=m[p++],--c;);0===r.length&&(r.mode=21);break;case 26:if(0===h)break t;n[a++]=r.length,h--,r.mode=21;break;case 27:if(r.wrap){for(;l<32;){if(0===o)break t;o--,u|=i[s++]<<l,l+=8}if(d-=h,t.total_out+=d,r.total+=d,d&&(t.adler=r.check=r.flags?B(r.check,n,d,a-d):O(r.check,n,d,a-d)),d=h,(r.flags?u:L(u))!==r.check){t.msg="incorrect data check",r.mode=30;break}l=u=0}r.mode=28;case 28:if(r.wrap&&r.flags){for(;l<32;){if(0===o)break t;o--,u+=i[s++]<<l,l+=8}if(u!==(4294967295&r.total)){t.msg="incorrect length check",r.mode=30;break}l=u=0}r.mode=29;case 29:x=1;break t;case 30:x=-3;break t;case 31:return-4;case 32:default:return U}return t.next_out=a,t.avail_out=h,t.next_in=s,t.avail_in=o,r.hold=u,r.bits=l,(r.wsize||d!==t.avail_out&&r.mode<30&&(r.mode<27||4!==e))&&Z(t,t.output,t.next_out,d-t.avail_out)?(r.mode=31,-4):(f-=t.avail_in,d-=t.avail_out,t.total_in+=f,t.total_out+=d,r.total+=d,r.wrap&&d&&(t.adler=r.check=r.flags?B(r.check,n,d,t.next_out-d):O(r.check,n,d,t.next_out-d)),t.data_type=r.bits+(r.last?64:0)+(12===r.mode?128:0)+(20===r.mode||15===r.mode?256:0),(0==f&&0===d||4===e)&&x===N&&(x=-5),x)},r.inflateEnd=function(t){if(!t||!t.state)return U;var e=t.state;return e.window&&(e.window=null),t.state=null,N},r.inflateGetHeader=function(t,e){var r;return t&&t.state?0==(2&(r=t.state).wrap)?U:((r.head=e).done=!1,N):U},r.inflateSetDictionary=function(t,e){var r,i=e.length;return t&&t.state?0!==(r=t.state).wrap&&11!==r.mode?U:11===r.mode&&O(1,e,i,0)!==r.check?-3:Z(t,e,i,i)?(r.mode=31,-4):(r.havedict=1,N):U},r.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(t,e,r){"use strict";var D=t("../utils/common"),F=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],N=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],U=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],P=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(t,e,r,i,n,s,a,o){var h,u,l,f,d,c,p,m,_,g=o.bits,b=0,v=0,y=0,w=0,k=0,x=0,S=0,z=0,C=0,E=0,A=null,I=0,O=new D.Buf16(16),B=new D.Buf16(16),R=null,T=0;for(b=0;b<=15;b++)O[b]=0;for(v=0;v<i;v++)O[e[r+v]]++;for(k=g,w=15;1<=w&&0===O[w];w--);if(w<k&&(k=w),0===w)return n[s++]=20971520,n[s++]=20971520,o.bits=1,0;for(y=1;y<w&&0===O[y];y++);for(k<y&&(k=y),b=z=1;b<=15;b++)if(z<<=1,(z-=O[b])<0)return-1;if(0<z&&(0===t||1!==w))return-1;for(B[1]=0,b=1;b<15;b++)B[b+1]=B[b]+O[b];for(v=0;v<i;v++)0!==e[r+v]&&(a[B[e[r+v]]++]=v);if(c=0===t?(A=R=a,19):1===t?(A=F,I-=257,R=N,T-=257,256):(A=U,R=P,-1),b=y,d=s,S=v=E=0,l=-1,f=(C=1<<(x=k))-1,1===t&&852<C||2===t&&592<C)return 1;for(;;){for(p=b-S,_=a[v]<c?(m=0,a[v]):a[v]>c?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<<b-S,y=u=1<<x;n[d+(E>>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<<b-1;E&h;)h>>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=e[r+a[v]]}if(k<b&&(E&f)!==l){for(0===S&&(S=k),d+=y,z=1<<(x=b-S);x+S<w&&!((z-=O[x+S])<=0);)x++,z<<=1;if(C+=1<<x,1===t&&852<C||2===t&&592<C)return 1;n[l=E&f]=k<<24|x<<16|d-s|0}}return 0!==E&&(n[d+E]=b-S<<24|64<<16|0),o.bits=k,0}},{"../utils/common":41}],51:[function(t,e,r){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],52:[function(t,e,r){"use strict";var n=t("../utils/common"),o=0,h=1;function i(t){for(var e=t.length;0<=--e;)t[e]=0}var s=0,a=29,u=256,l=u+1+a,f=30,d=19,_=2*l+1,g=15,c=16,p=7,m=256,b=16,v=17,y=18,w=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],k=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],x=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],S=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],z=new Array(2*(l+2));i(z);var C=new Array(2*f);i(C);var E=new Array(512);i(E);var A=new Array(256);i(A);var I=new Array(a);i(I);var O,B,R,T=new Array(f);function D(t,e,r,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=r,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}function F(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}function N(t){return t<256?E[t]:E[256+(t>>>7)]}function U(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function P(t,e,r){t.bi_valid>c-r?(t.bi_buf|=e<<t.bi_valid&65535,U(t,t.bi_buf),t.bi_buf=e>>c-t.bi_valid,t.bi_valid+=r-c):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=r)}function L(t,e,r){P(t,r[2*e],r[2*e+1])}function j(t,e){for(var r=0;r|=1&t,t>>>=1,r<<=1,0<--e;);return r>>>1}function Z(t,e,r){var i,n,s=new Array(g+1),a=0;for(i=1;i<=g;i++)s[i]=a=a+r[i-1]<<1;for(n=0;n<=e;n++){var o=t[2*n+1];0!==o&&(t[2*n]=j(s[o]++,o))}}function W(t){var e;for(e=0;e<l;e++)t.dyn_ltree[2*e]=0;for(e=0;e<f;e++)t.dyn_dtree[2*e]=0;for(e=0;e<d;e++)t.bl_tree[2*e]=0;t.dyn_ltree[2*m]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function M(t){8<t.bi_valid?U(t,t.bi_buf):0<t.bi_valid&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0}function H(t,e,r,i){var n=2*e,s=2*r;return t[n]<t[s]||t[n]===t[s]&&i[e]<=i[r]}function G(t,e,r){for(var i=t.heap[r],n=r<<1;n<=t.heap_len&&(n<t.heap_len&&H(e,t.heap[n+1],t.heap[n],t.depth)&&n++,!H(e,i,t.heap[n],t.depth));)t.heap[r]=t.heap[n],r=n,n<<=1;t.heap[r]=i}function K(t,e,r){var i,n,s,a,o=0;if(0!==t.last_lit)for(;i=t.pending_buf[t.d_buf+2*o]<<8|t.pending_buf[t.d_buf+2*o+1],n=t.pending_buf[t.l_buf+o],o++,0===i?L(t,n,e):(L(t,(s=A[n])+u+1,e),0!==(a=w[s])&&P(t,n-=I[s],a),L(t,s=N(--i),r),0!==(a=k[s])&&P(t,i-=T[s],a)),o<t.last_lit;);L(t,m,e)}function Y(t,e){var r,i,n,s=e.dyn_tree,a=e.stat_desc.static_tree,o=e.stat_desc.has_stree,h=e.stat_desc.elems,u=-1;for(t.heap_len=0,t.heap_max=_,r=0;r<h;r++)0!==s[2*r]?(t.heap[++t.heap_len]=u=r,t.depth[r]=0):s[2*r+1]=0;for(;t.heap_len<2;)s[2*(n=t.heap[++t.heap_len]=u<2?++u:0)]=1,t.depth[n]=0,t.opt_len--,o&&(t.static_len-=a[2*n+1]);for(e.max_code=u,r=t.heap_len>>1;1<=r;r--)G(t,s,r);for(n=h;r=t.heap[1],t.heap[1]=t.heap[t.heap_len--],G(t,s,1),i=t.heap[1],t.heap[--t.heap_max]=r,t.heap[--t.heap_max]=i,s[2*n]=s[2*r]+s[2*i],t.depth[n]=(t.depth[r]>=t.depth[i]?t.depth[r]:t.depth[i])+1,s[2*r+1]=s[2*i+1]=n,t.heap[1]=n++,G(t,s,1),2<=t.heap_len;);t.heap[--t.heap_max]=t.heap[1],function(t,e){var r,i,n,s,a,o,h=e.dyn_tree,u=e.max_code,l=e.stat_desc.static_tree,f=e.stat_desc.has_stree,d=e.stat_desc.extra_bits,c=e.stat_desc.extra_base,p=e.stat_desc.max_length,m=0;for(s=0;s<=g;s++)t.bl_count[s]=0;for(h[2*t.heap[t.heap_max]+1]=0,r=t.heap_max+1;r<_;r++)p<(s=h[2*h[2*(i=t.heap[r])+1]+1]+1)&&(s=p,m++),h[2*i+1]=s,u<i||(t.bl_count[s]++,a=0,c<=i&&(a=d[i-c]),o=h[2*i],t.opt_len+=o*(s+a),f&&(t.static_len+=o*(l[2*i+1]+a)));if(0!==m){do{for(s=p-1;0===t.bl_count[s];)s--;t.bl_count[s]--,t.bl_count[s+1]+=2,t.bl_count[p]--,m-=2}while(0<m);for(s=p;0!==s;s--)for(i=t.bl_count[s];0!==i;)u<(n=t.heap[--r])||(h[2*n+1]!==s&&(t.opt_len+=(s-h[2*n+1])*h[2*n],h[2*n+1]=s),i--)}}(t,e),Z(s,u,t.bl_count)}function X(t,e,r){var i,n,s=-1,a=e[1],o=0,h=7,u=4;for(0===a&&(h=138,u=3),e[2*(r+1)+1]=65535,i=0;i<=r;i++)n=a,a=e[2*(i+1)+1],++o<h&&n===a||(o<u?t.bl_tree[2*n]+=o:0!==n?(n!==s&&t.bl_tree[2*n]++,t.bl_tree[2*b]++):o<=10?t.bl_tree[2*v]++:t.bl_tree[2*y]++,s=n,u=(o=0)===a?(h=138,3):n===a?(h=6,3):(h=7,4))}function V(t,e,r){var i,n,s=-1,a=e[1],o=0,h=7,u=4;for(0===a&&(h=138,u=3),i=0;i<=r;i++)if(n=a,a=e[2*(i+1)+1],!(++o<h&&n===a)){if(o<u)for(;L(t,n,t.bl_tree),0!=--o;);else 0!==n?(n!==s&&(L(t,n,t.bl_tree),o--),L(t,b,t.bl_tree),P(t,o-3,2)):o<=10?(L(t,v,t.bl_tree),P(t,o-3,3)):(L(t,y,t.bl_tree),P(t,o-11,7));s=n,u=(o=0)===a?(h=138,3):n===a?(h=6,3):(h=7,4)}}i(T);var q=!1;function J(t,e,r,i){P(t,(s<<1)+(i?1:0),3),function(t,e,r,i){M(t),i&&(U(t,r),U(t,~r)),n.arraySet(t.pending_buf,t.window,e,r,t.pending),t.pending+=r}(t,e,r,!0)}r._tr_init=function(t){q||(function(){var t,e,r,i,n,s=new Array(g+1);for(i=r=0;i<a-1;i++)for(I[i]=r,t=0;t<1<<w[i];t++)A[r++]=i;for(A[r-1]=i,i=n=0;i<16;i++)for(T[i]=n,t=0;t<1<<k[i];t++)E[n++]=i;for(n>>=7;i<f;i++)for(T[i]=n<<7,t=0;t<1<<k[i]-7;t++)E[256+n++]=i;for(e=0;e<=g;e++)s[e]=0;for(t=0;t<=143;)z[2*t+1]=8,t++,s[8]++;for(;t<=255;)z[2*t+1]=9,t++,s[9]++;for(;t<=279;)z[2*t+1]=7,t++,s[7]++;for(;t<=287;)z[2*t+1]=8,t++,s[8]++;for(Z(z,l+1,s),t=0;t<f;t++)C[2*t+1]=5,C[2*t]=j(t,5);O=new D(z,w,u+1,l,g),B=new D(C,k,0,f,g),R=new D(new Array(0),x,0,d,p)}(),q=!0),t.l_desc=new F(t.dyn_ltree,O),t.d_desc=new F(t.dyn_dtree,B),t.bl_desc=new F(t.bl_tree,R),t.bi_buf=0,t.bi_valid=0,W(t)},r._tr_stored_block=J,r._tr_flush_block=function(t,e,r,i){var n,s,a=0;0<t.level?(2===t.strm.data_type&&(t.strm.data_type=function(t){var e,r=4093624447;for(e=0;e<=31;e++,r>>>=1)if(1&r&&0!==t.dyn_ltree[2*e])return o;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return h;for(e=32;e<u;e++)if(0!==t.dyn_ltree[2*e])return h;return o}(t)),Y(t,t.l_desc),Y(t,t.d_desc),a=function(t){var e;for(X(t,t.dyn_ltree,t.l_desc.max_code),X(t,t.dyn_dtree,t.d_desc.max_code),Y(t,t.bl_desc),e=d-1;3<=e&&0===t.bl_tree[2*S[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}(t),n=t.opt_len+3+7>>>3,(s=t.static_len+3+7>>>3)<=n&&(n=s)):n=s=r+5,r+4<=n&&-1!==e?J(t,e,r,i):4===t.strategy||s===n?(P(t,2+(i?1:0),3),K(t,z,C)):(P(t,4+(i?1:0),3),function(t,e,r,i){var n;for(P(t,e-257,5),P(t,r-1,5),P(t,i-4,4),n=0;n<i;n++)P(t,t.bl_tree[2*S[n]+1],3);V(t,t.dyn_ltree,e-1),V(t,t.dyn_dtree,r-1)}(t,t.l_desc.max_code+1,t.d_desc.max_code+1,a+1),K(t,t.dyn_ltree,t.dyn_dtree)),W(t),i&&M(t)},r._tr_tally=function(t,e,r){return t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&r,t.last_lit++,0===e?t.dyn_ltree[2*r]++:(t.matches++,e--,t.dyn_ltree[2*(A[r]+u+1)]++,t.dyn_dtree[2*N(e)]++),t.last_lit===t.lit_bufsize-1},r._tr_align=function(t){P(t,2,3),L(t,m,z),function(t){16===t.bi_valid?(U(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):8<=t.bi_valid&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}(t)}},{"../utils/common":41}],53:[function(t,e,r){"use strict";e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(t,e,r){"use strict";e.exports="function"==typeof setImmediate?setImmediate:function(){var t=[].slice.apply(arguments);t.splice(1,0,0),setTimeout.apply(null,t)}},{}]},{},[10])(10)});
32400/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(17).Buffer, __webpack_require__(2), __webpack_require__(21).setImmediate)) 32401 32402/***/ }), 32403/* 17 */ 32404/***/ (function(module, exports, __webpack_require__) { 32405 32406"use strict"; 32407/* WEBPACK VAR INJECTION */(function(global) {/*! 32408 * The buffer module from node.js, for the browser. 32409 * 32410 * @author Feross Aboukhadijeh <http://feross.org> 32411 * @license MIT 32412 */ 32413/* eslint-disable no-proto */ 32414 32415 32416 32417var base64 = __webpack_require__(18) 32418var ieee754 = __webpack_require__(19) 32419var isArray = __webpack_require__(20
vendor: 48,375 bytes, lines 32419-34197
32419) 32420 32421exports.Buffer = Buffer 32422exports.SlowBuffer = SlowBuffer 32423exports.INSPECT_MAX_BYTES = 50 32424 32425/** 32426 * If `Buffer.TYPED_ARRAY_SUPPORT`: 32427 * === true Use Uint8Array implementation (fastest) 32428 * === false Use Object implementation (most compatible, even IE6) 32429 * 32430 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, 32431 * Opera 11.6+, iOS 4.2+. 32432 * 32433 * Due to various browser bugs, sometimes the Object implementation will be used even 32434 * when the browser supports typed arrays. 32435 * 32436 * Note: 32437 * 32438 * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, 32439 * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. 32440 * 32441 * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. 32442 * 32443 * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of 32444 * incorrect length in some situations. 32445 32446 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they 32447 * get the Object implementation, which is slower but behaves correctly. 32448 */ 32449Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined 32450 ? global.TYPED_ARRAY_SUPPORT 32451 : typedArraySupport() 32452 32453/* 32454 * Export kMaxLength after typed array support is determined. 32455 */ 32456exports.kMaxLength = kMaxLength() 32457 32458function typedArraySupport () { 32459 try { 32460 var arr = new Uint8Array(1) 32461 arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} 32462 return arr.foo() === 42 && // typed array instances can be augmented 32463 typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` 32464 arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` 32465 } catch (e) { 32466 return false 32467 } 32468} 32469 32470function kMaxLength () { 32471 return Buffer.TYPED_ARRAY_SUPPORT 32472 ? 0x7fffffff 32473 : 0x3fffffff 32474} 32475 32476function createBuffer (that, length) { 32477 if (kMaxLength() < length) { 32478 throw new RangeError('Invalid typed array length') 32479 } 32480 if (Buffer.TYPED_ARRAY_SUPPORT) { 32481 // Return an augmented `Uint8Array` instance, for best performance 32482 that = new Uint8Array(length) 32483 that.__proto__ = Buffer.prototype 32484 } else { 32485 // Fallback: Return an object instance of the Buffer class 32486 if (that === null) { 32487 that = new Buffer(length) 32488 } 32489 that.length = length 32490 } 32491 32492 return that 32493} 32494 32495/** 32496 * The Buffer constructor returns instances of `Uint8Array` that have their 32497 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of 32498 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods 32499 * and the `Uint8Array` methods. Square bracket notation works as expected -- it 32500 * returns a single octet. 32501 * 32502 * The `Uint8Array` prototype remains unmodified. 32503 */ 32504 32505function Buffer (arg, encodingOrOffset, length) { 32506 if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { 32507 return new Buffer(arg, encodingOrOffset, length) 32508 } 32509 32510 // Common case. 32511 if (typeof arg === 'number') { 32512 if (typeof encodingOrOffset === 'string') { 32513 throw new Error( 32514 'If encoding is specified then the first argument must be a string' 32515 ) 32516 } 32517 return allocUnsafe(this, arg) 32518 } 32519 return from(this, arg, encodingOrOffset, length) 32520} 32521 32522Buffer.poolSize = 8192 // not used by this implementation 32523 32524// TODO: Legacy, not needed anymore. Remove in next major version. 32525Buffer._augment = function (arr) { 32526 arr.__proto__ = Buffer.prototype 32527 return arr 32528} 32529 32530function from (that, value, encodingOrOffset, length) { 32531 if (typeof value === 'number') { 32532 throw new TypeError('"value" argument must not be a number') 32533 } 32534 32535 if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { 32536 return fromArrayBuffer(that, value, encodingOrOffset, length) 32537 } 32538 32539 if (typeof value === 'string') { 32540 return fromString(that, value, encodingOrOffset) 32541 } 32542 32543 return fromObject(that, value) 32544} 32545 32546/** 32547 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError 32548 * if value is a number. 32549 * Buffer.from(str[, encoding]) 32550 * Buffer.from(array) 32551 * Buffer.from(buffer) 32552 * Buffer.from(arrayBuffer[, byteOffset[, length]]) 32553 **/ 32554Buffer.from = function (value, encodingOrOffset, length) { 32555 return from(null, value, encodingOrOffset, length) 32556} 32557 32558if (Buffer.TYPED_ARRAY_SUPPORT) { 32559 Buffer.prototype.__proto__ = Uint8Array.prototype 32560 Buffer.__proto__ = Uint8Array 32561 if (typeof Symbol !== 'undefined' && Symbol.species && 32562 Buffer[Symbol.species] === Buffer) { 32563 // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 32564 Object.defineProperty(Buffer, Symbol.species, { 32565 value: null, 32566 configurable: true 32567 }) 32568 } 32569} 32570 32571function assertSize (size) { 32572 if (typeof size !== 'number') { 32573 throw new TypeError('"size" argument must be a number') 32574 } else if (size < 0) { 32575 throw new RangeError('"size" argument must not be negative') 32576 } 32577} 32578 32579function alloc (that, size, fill, encoding) { 32580 assertSize(size) 32581 if (size <= 0) { 32582 return createBuffer(that, size) 32583 } 32584 if (fill !== undefined) { 32585 // Only pay attention to encoding if it's a string. This 32586 // prevents accidentally sending in a number that would 32587 // be interpretted as a start offset. 32588 return typeof encoding === 'string' 32589 ? createBuffer(that, size).fill(fill, encoding) 32590 : createBuffer(that, size).fill(fill) 32591 } 32592 return createBuffer(that, size) 32593} 32594 32595/** 32596 * Creates a new filled Buffer instance. 32597 * alloc(size[, fill[, encoding]]) 32598 **/ 32599Buffer.alloc = function (size, fill, encoding) { 32600 return alloc(null, size, fill, encoding) 32601} 32602 32603function allocUnsafe (that, size) { 32604 assertSize(size) 32605 that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) 32606 if (!Buffer.TYPED_ARRAY_SUPPORT) { 32607 for (var i = 0; i < size; ++i) { 32608 that[i] = 0 32609 } 32610 } 32611 return that 32612} 32613 32614/** 32615 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. 32616 * */ 32617Buffer.allocUnsafe = function (size) { 32618 return allocUnsafe(null, size) 32619} 32620/** 32621 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. 32622 */ 32623Buffer.allocUnsafeSlow = function (size) { 32624 return allocUnsafe(null, size) 32625} 32626 32627function fromString (that, string, encoding) { 32628 if (typeof encoding !== 'string' || encoding === '') { 32629 encoding = 'utf8' 32630 } 32631 32632 if (!Buffer.isEncoding(encoding)) { 32633 throw new TypeError('"encoding" must be a valid string encoding') 32634 } 32635 32636 var length = byteLength(string, encoding) | 0 32637 that = createBuffer(that, length) 32638 32639 var actual = that.write(string, encoding) 32640 32641 if (actual !== length) { 32642 // Writing a hex string, for example, that contains invalid characters will 32643 // cause everything after the first invalid character to be ignored. (e.g. 32644 // 'abxxcd' will be treated as 'ab') 32645 that = that.slice(0, actual) 32646 } 32647 32648 return that 32649} 32650 32651function fromArrayLike (that, array) { 32652 var length = array.length < 0 ? 0 : checked(array.length) | 0 32653 that = createBuffer(that, length) 32654 for (var i = 0; i < length; i += 1) { 32655 that[i] = array[i] & 255 32656 } 32657 return that 32658} 32659 32660function fromArrayBuffer (that, array, byteOffset, length) { 32661 array.byteLength // this throws if `array` is not a valid ArrayBuffer 32662 32663 if (byteOffset < 0 || array.byteLength < byteOffset) { 32664 throw new RangeError('\'offset\' is out of bounds') 32665 } 32666 32667 if (array.byteLength < byteOffset + (length || 0)) { 32668 throw new RangeError('\'length\' is out of bounds') 32669 } 32670 32671 if (byteOffset === undefined && length === undefined) { 32672 array = new Uint8Array(array) 32673 } else if (length === undefined) { 32674 array = new Uint8Array(array, byteOffset) 32675 } else { 32676 array = new Uint8Array(array, byteOffset, length) 32677 } 32678 32679 if (Buffer.TYPED_ARRAY_SUPPORT) { 32680 // Return an augmented `Uint8Array` instance, for best performance 32681 that = array 32682 that.__proto__ = Buffer.prototype 32683 } else { 32684 // Fallback: Return an object instance of the Buffer class 32685 that = fromArrayLike(that, array) 32686 } 32687 return that 32688} 32689 32690function fromObject (that, obj) { 32691 if (Buffer.isBuffer(obj)) { 32692 var len = checked(obj.length) | 0 32693 that = createBuffer(that, len) 32694 32695 if (that.length === 0) { 32696 return that 32697 } 32698 32699 obj.copy(that, 0, 0, len) 32700 return that 32701 } 32702 32703 if (obj) { 32704 if ((typeof ArrayBuffer !== 'undefined' && 32705 obj.buffer instanceof ArrayBuffer) || 'length' in obj) { 32706 if (typeof obj.length !== 'number' || isnan(obj.length)) { 32707 return createBuffer(that, 0) 32708 } 32709 return fromArrayLike(that, obj) 32710 } 32711 32712 if (obj.type === 'Buffer' && isArray(obj.data)) { 32713 return fromArrayLike(that, obj.data) 32714 } 32715 } 32716 32717 throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') 32718} 32719 32720function checked (length) { 32721 // Note: cannot use `length < kMaxLength()` here because that fails when 32722 // length is NaN (which is otherwise coerced to zero.) 32723 if (length >= kMaxLength()) { 32724 throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 32725 'size: 0x' + kMaxLength().toString(16) + ' bytes') 32726 } 32727 return length | 0 32728} 32729 32730function SlowBuffer (length) { 32731 if (+length != length) { // eslint-disable-line eqeqeq 32732 length = 0 32733 } 32734 return Buffer.alloc(+length) 32735} 32736 32737Buffer.isBuffer = function isBuffer (b) { 32738 return !!(b != null && b._isBuffer) 32739} 32740 32741Buffer.compare = function compare (a, b) { 32742 if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { 32743 throw new TypeError('Arguments must be Buffers') 32744 } 32745 32746 if (a === b) return 0 32747 32748 var x = a.length 32749 var y = b.length 32750 32751 for (var i = 0, len = Math.min(x, y); i < len; ++i) { 32752 if (a[i] !== b[i]) { 32753 x = a[i] 32754 y = b[i] 32755 break 32756 } 32757 } 32758 32759 if (x < y) return -1 32760 if (y < x) return 1 32761 return 0 32762} 32763 32764Buffer.isEncoding = function isEncoding (encoding) { 32765 switch (String(encoding).toLowerCase()) { 32766 case 'hex': 32767 case 'utf8': 32768 case 'utf-8': 32769 case 'ascii': 32770 case 'latin1': 32771 case 'binary': 32772 case 'base64': 32773 case 'ucs2': 32774 case 'ucs-2': 32775 case 'utf16le': 32776 case 'utf-16le': 32777 return true 32778 default: 32779 return false 32780 } 32781} 32782 32783Buffer.concat = function concat (list, length) { 32784 if (!isArray(list)) { 32785 throw new TypeError('"list" argument must be an Array of Buffers') 32786 } 32787 32788 if (list.length === 0) { 32789 return Buffer.alloc(0) 32790 } 32791 32792 var i 32793 if (length === undefined) { 32794 length = 0 32795 for (i = 0; i < list.length; ++i) { 32796 length += list[i].length 32797 } 32798 } 32799 32800 var buffer = Buffer.allocUnsafe(length) 32801 var pos = 0 32802 for (i = 0; i < list.length; ++i) { 32803 var buf = list[i] 32804 if (!Buffer.isBuffer(buf)) { 32805 throw new TypeError('"list" argument must be an Array of Buffers') 32806 } 32807 buf.copy(buffer, pos) 32808 pos += buf.length 32809 } 32810 return buffer 32811} 32812 32813function byteLength (string, encoding) { 32814 if (Buffer.isBuffer(string)) { 32815 return string.length 32816 } 32817 if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && 32818 (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { 32819 return string.byteLength 32820 } 32821 if (typeof string !== 'string') { 32822 string = '' + string 32823 } 32824 32825 var len = string.length 32826 if (len === 0) return 0 32827 32828 // Use a for loop to avoid recursion 32829 var loweredCase = false 32830 for (;;) { 32831 switch (encoding) { 32832 case 'ascii': 32833 case 'latin1': 32834 case 'binary': 32835 return len 32836 case 'utf8': 32837 case 'utf-8': 32838 case undefined: 32839 return utf8ToBytes(string).length 32840 case 'ucs2': 32841 case 'ucs-2': 32842 case 'utf16le': 32843 case 'utf-16le': 32844 return len * 2 32845 case 'hex': 32846 return len >>> 1 32847 case 'base64': 32848 return base64ToBytes(string).length 32849 default: 32850 if (loweredCase) return utf8ToBytes(string).length // assume utf8 32851 encoding = ('' + encoding).toLowerCase() 32852 loweredCase = true 32853 } 32854 } 32855} 32856Buffer.byteLength = byteLength 32857 32858function slowToString (encoding, start, end) { 32859 var loweredCase = false 32860 32861 // No need to verify that "this.length <= MAX_UINT32" since it's a read-only 32862 // property of a typed array. 32863 32864 // This behaves neither like String nor Uint8Array in that we set start/end 32865 // to their upper/lower bounds if the value passed is out of range. 32866 // undefined is handled specially as per ECMA-262 6th Edition, 32867 // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. 32868 if (start === undefined || start < 0) { 32869 start = 0 32870 } 32871 // Return early if start > this.length. Done here to prevent potential uint32 32872 // coercion fail below. 32873 if (start > this.length) { 32874 return '' 32875 } 32876 32877 if (end === undefined || end > this.length) { 32878 end = this.length 32879 } 32880 32881 if (end <= 0) { 32882 return '' 32883 } 32884 32885 // Force coersion to uint32. This will also coerce falsey/NaN values to 0. 32886 end >>>= 0 32887 start >>>= 0 32888 32889 if (end <= start) { 32890 return '' 32891 } 32892 32893 if (!encoding) encoding = 'utf8' 32894 32895 while (true) { 32896 switch (encoding) { 32897 case 'hex': 32898 return hexSlice(this, start, end) 32899 32900 case 'utf8': 32901 case 'utf-8': 32902 return utf8Slice(this, start, end) 32903 32904 case 'ascii': 32905 return asciiSlice(this, start, end) 32906 32907 case 'latin1': 32908 case 'binary': 32909 return latin1Slice(this, start, end) 32910 32911 case 'base64': 32912 return base64Slice(this, start, end) 32913 32914 case 'ucs2': 32915 case 'ucs-2': 32916 case 'utf16le': 32917 case 'utf-16le': 32918 return utf16leSlice(this, start, end) 32919 32920 default: 32921 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 32922 encoding = (encoding + '').toLowerCase() 32923 loweredCase = true 32924 } 32925 } 32926} 32927 32928// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect 32929// Buffer instances. 32930Buffer.prototype._isBuffer = true 32931 32932function swap (b, n, m) { 32933 var i = b[n] 32934 b[n] = b[m] 32935 b[m] = i 32936} 32937 32938Buffer.prototype.swap16 = function swap16 () { 32939 var len = this.length 32940 if (len % 2 !== 0) { 32941 throw new RangeError('Buffer size must be a multiple of 16-bits') 32942 } 32943 for (var i = 0; i < len; i += 2) { 32944 swap(this, i, i + 1) 32945 } 32946 return this 32947} 32948 32949Buffer.prototype.swap32 = function swap32 () { 32950 var len = this.length 32951 if (len % 4 !== 0) { 32952 throw new RangeError('Buffer size must be a multiple of 32-bits') 32953 } 32954 for (var i = 0; i < len; i += 4) { 32955 swap(this, i, i + 3) 32956 swap(this, i + 1, i + 2) 32957 } 32958 return this 32959} 32960 32961Buffer.prototype.swap64 = function swap64 () { 32962 var len = this.length 32963 if (len % 8 !== 0) { 32964 throw new RangeError('Buffer size must be a multiple of 64-bits') 32965 } 32966 for (var i = 0; i < len; i += 8) { 32967 swap(this, i, i + 7) 32968 swap(this, i + 1, i + 6) 32969 swap(this, i + 2, i + 5) 32970 swap(this, i + 3, i + 4) 32971 } 32972 return this 32973} 32974 32975Buffer.prototype.toString = function toString () { 32976 var length = this.length | 0 32977 if (length === 0) return '' 32978 if (arguments.length === 0) return utf8Slice(this, 0, length) 32979 return slowToString.apply(this, arguments) 32980} 32981 32982Buffer.prototype.equals = function equals (b) { 32983 if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 32984 if (this === b) return true 32985 return Buffer.compare(this, b) === 0 32986} 32987 32988Buffer.prototype.inspect = function inspect () { 32989 var str = '' 32990 var max = exports.INSPECT_MAX_BYTES 32991 if (this.length > 0) { 32992 str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') 32993 if (this.length > max) str += ' ... ' 32994 } 32995 return '<Buffer ' + str + '>' 32996} 32997 32998Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { 32999 if (!Buffer.isBuffer(target)) { 33000 throw new TypeError('Argument must be a Buffer') 33001 } 33002 33003 if (start === undefined) { 33004 start = 0 33005 } 33006 if (end === undefined) { 33007 end = target ? target.length : 0 33008 } 33009 if (thisStart === undefined) { 33010 thisStart = 0 33011 } 33012 if (thisEnd === undefined) { 33013 thisEnd = this.length 33014 } 33015 33016 if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { 33017 throw new RangeError('out of range index') 33018 } 33019 33020 if (thisStart >= thisEnd && start >= end) { 33021 return 0 33022 } 33023 if (thisStart >= thisEnd) { 33024 return -1 33025 } 33026 if (start >= end) { 33027 return 1 33028 } 33029 33030 start >>>= 0 33031 end >>>= 0 33032 thisStart >>>= 0 33033 thisEnd >>>= 0 33034 33035 if (this === target) return 0 33036 33037 var x = thisEnd - thisStart 33038 var y = end - start 33039 var len = Math.min(x, y) 33040 33041 var thisCopy = this.slice(thisStart, thisEnd) 33042 var targetCopy = target.slice(start, end) 33043 33044 for (var i = 0; i < len; ++i) { 33045 if (thisCopy[i] !== targetCopy[i]) { 33046 x = thisCopy[i] 33047 y = targetCopy[i] 33048 break 33049 } 33050 } 33051 33052 if (x < y) return -1 33053 if (y < x) return 1 33054 return 0 33055} 33056 33057// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, 33058// OR the last index of `val` in `buffer` at offset <= `byteOffset`. 33059// 33060// Arguments: 33061// - buffer - a Buffer to search 33062// - val - a string, Buffer, or number 33063// - byteOffset - an index into `buffer`; will be clamped to an int32 33064// - encoding - an optional encoding, relevant is val is a string 33065// - dir - true for indexOf, false for lastIndexOf 33066function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { 33067 // Empty buffer means no match 33068 if (buffer.length === 0) return -1 33069 33070 // Normalize byteOffset 33071 if (typeof byteOffset === 'string') { 33072 encoding = byteOffset 33073 byteOffset = 0 33074 } else if (byteOffset > 0x7fffffff) { 33075 byteOffset = 0x7fffffff 33076 } else if (byteOffset < -0x80000000) { 33077 byteOffset = -0x80000000 33078 } 33079 byteOffset = +byteOffset // Coerce to Number. 33080 if (isNaN(byteOffset)) { 33081 // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer 33082 byteOffset = dir ? 0 : (buffer.length - 1) 33083 } 33084 33085 // Normalize byteOffset: negative offsets start from the end of the buffer 33086 if (byteOffset < 0) byteOffset = buffer.length + byteOffset 33087 if (byteOffset >= buffer.length) { 33088 if (dir) return -1 33089 else byteOffset = buffer.length - 1 33090 } else if (byteOffset < 0) { 33091 if (dir) byteOffset = 0 33092 else return -1 33093 } 33094 33095 // Normalize val 33096 if (typeof val === 'string') { 33097 val = Buffer.from(val, encoding) 33098 } 33099 33100 // Finally, search either indexOf (if dir is true) or lastIndexOf 33101 if (Buffer.isBuffer(val)) { 33102 // Special case: looking for empty string/buffer always fails 33103 if (val.length === 0) { 33104 return -1 33105 } 33106 return arrayIndexOf(buffer, val, byteOffset, encoding, dir) 33107 } else if (typeof val === 'number') { 33108 val = val & 0xFF // Search for a byte value [0-255] 33109 if (Buffer.TYPED_ARRAY_SUPPORT && 33110 typeof Uint8Array.prototype.indexOf === 'function') { 33111 if (dir) { 33112 return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) 33113 } else { 33114 return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) 33115 } 33116 } 33117 return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) 33118 } 33119 33120 throw new TypeError('val must be string, number or Buffer') 33121} 33122 33123function arrayIndexOf (arr, val, byteOffset, encoding, dir) { 33124 var indexSize = 1 33125 var arrLength = arr.length 33126 var valLength = val.length 33127 33128 if (encoding !== undefined) { 33129 encoding = String(encoding).toLowerCase() 33130 if (encoding === 'ucs2' || encoding === 'ucs-2' || 33131 encoding === 'utf16le' || encoding === 'utf-16le') { 33132 if (arr.length < 2 || val.length < 2) { 33133 return -1 33134 } 33135 indexSize = 2 33136 arrLength /= 2 33137 valLength /= 2 33138 byteOffset /= 2 33139 } 33140 } 33141 33142 function read (buf, i) { 33143 if (indexSize === 1) { 33144 return buf[i] 33145 } else { 33146 return buf.readUInt16BE(i * indexSize) 33147 } 33148 } 33149 33150 var i 33151 if (dir) { 33152 var foundIndex = -1 33153 for (i = byteOffset; i < arrLength; i++) { 33154 if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { 33155 if (foundIndex === -1) foundIndex = i 33156 if (i - foundIndex + 1 === valLength) return foundIndex * indexSize 33157 } else { 33158 if (foundIndex !== -1) i -= i - foundIndex 33159 foundIndex = -1 33160 } 33161 } 33162 } else { 33163 if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength 33164 for (i = byteOffset; i >= 0; i--) { 33165 var found = true 33166 for (var j = 0; j < valLength; j++) { 33167 if (read(arr, i + j) !== read(val, j)) { 33168 found = false 33169 break 33170 } 33171 } 33172 if (found) return i 33173 } 33174 } 33175 33176 return -1 33177} 33178 33179Buffer.prototype.includes = function includes (val, byteOffset, encoding) { 33180 return this.indexOf(val, byteOffset, encoding) !== -1 33181} 33182 33183Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { 33184 return bidirectionalIndexOf(this, val, byteOffset, encoding, true) 33185} 33186 33187Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { 33188 return bidirectionalIndexOf(this, val, byteOffset, encoding, false) 33189} 33190 33191function hexWrite (buf, string, offset, length) { 33192 offset = Number(offset) || 0 33193 var remaining = buf.length - offset 33194 if (!length) { 33195 length = remaining 33196 } else { 33197 length = Number(length) 33198 if (length > remaining) { 33199 length = remaining 33200 } 33201 } 33202 33203 // must be an even number of digits 33204 var strLen = string.length 33205 if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') 33206 33207 if (length > strLen / 2) { 33208 length = strLen / 2 33209 } 33210 for (var i = 0; i < length; ++i) { 33211 var parsed = parseInt(string.substr(i * 2, 2), 16) 33212 if (isNaN(parsed)) return i 33213 buf[offset + i] = parsed 33214 } 33215 return i 33216} 33217 33218function utf8Write (buf, string, offset, length) { 33219 return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) 33220} 33221 33222function asciiWrite (buf, string, offset, length) { 33223 return blitBuffer(asciiToBytes(string), buf, offset, length) 33224} 33225 33226function latin1Write (buf, string, offset, length) { 33227 return asciiWrite(buf, string, offset, length) 33228} 33229 33230function base64Write (buf, string, offset, length) { 33231 return blitBuffer(base64ToBytes(string), buf, offset, length) 33232} 33233 33234function ucs2Write (buf, string, offset, length) { 33235 return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) 33236} 33237 33238Buffer.prototype.write = function write (string, offset, length, encoding) { 33239 // Buffer#write(string) 33240 if (offset === undefined) { 33241 encoding = 'utf8' 33242 length = this.length 33243 offset = 0 33244 // Buffer#write(string, encoding) 33245 } else if (length === undefined && typeof offset === 'string') { 33246 encoding = offset 33247 length = this.length 33248 offset = 0 33249 // Buffer#write(string, offset[, length][, encoding]) 33250 } else if (isFinite(offset)) { 33251 offset = offset | 0 33252 if (isFinite(length)) { 33253 length = length | 0 33254 if (encoding === undefined) encoding = 'utf8' 33255 } else { 33256 encoding = length 33257 length = undefined 33258 } 33259 // legacy write(string, encoding, offset, length) - remove in v0.13 33260 } else { 33261 throw new Error( 33262 'Buffer.write(string, encoding, offset[, length]) is no longer supported' 33263 ) 33264 } 33265 33266 var remaining = this.length - offset 33267 if (length === undefined || length > remaining) length = remaining 33268 33269 if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { 33270 throw new RangeError('Attempt to write outside buffer bounds') 33271 } 33272 33273 if (!encoding) encoding = 'utf8' 33274 33275 var loweredCase = false 33276 for (;;) { 33277 switch (encoding) { 33278 case 'hex': 33279 return hexWrite(this, string, offset, length) 33280 33281 case 'utf8': 33282 case 'utf-8': 33283 return utf8Write(this, string, offset, length) 33284 33285 case 'ascii': 33286 return asciiWrite(this, string, offset, length) 33287 33288 case 'latin1': 33289 case 'binary': 33290 return latin1Write(this, string, offset, length) 33291 33292 case 'base64': 33293 // Warning: maxLength not taken into account in base64Write 33294 return base64Write(this, string, offset, length) 33295 33296 case 'ucs2': 33297 case 'ucs-2': 33298 case 'utf16le': 33299 case 'utf-16le': 33300 return ucs2Write(this, string, offset, length) 33301 33302 default: 33303 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 33304 encoding = ('' + encoding).toLowerCase() 33305 loweredCase = true 33306 } 33307 } 33308} 33309 33310Buffer.prototype.toJSON = function toJSON () { 33311 return { 33312 type: 'Buffer', 33313 data: Array.prototype.slice.call(this._arr || this, 0) 33314 } 33315} 33316 33317function base64Slice (buf, start, end) { 33318 if (start === 0 && end === buf.length) { 33319 return base64.fromByteArray(buf) 33320 } else { 33321 return base64.fromByteArray(buf.slice(start, end)) 33322 } 33323} 33324 33325function utf8Slice (buf, start, end) { 33326 end = Math.min(buf.length, end) 33327 var res = [] 33328 33329 var i = start 33330 while (i < end) { 33331 var firstByte = buf[i] 33332 var codePoint = null 33333 var bytesPerSequence = (firstByte > 0xEF) ? 4 33334 : (firstByte > 0xDF) ? 3 33335 : (firstByte > 0xBF) ? 2 33336 : 1 33337 33338 if (i + bytesPerSequence <= end) { 33339 var secondByte, thirdByte, fourthByte, tempCodePoint 33340 33341 switch (bytesPerSequence) { 33342 case 1: 33343 if (firstByte < 0x80) { 33344 codePoint = firstByte 33345 } 33346 break 33347 case 2: 33348 secondByte = buf[i + 1] 33349 if ((secondByte & 0xC0) === 0x80) { 33350 tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) 33351 if (tempCodePoint > 0x7F) { 33352 codePoint = tempCodePoint 33353 } 33354 } 33355 break 33356 case 3: 33357 secondByte = buf[i + 1] 33358 thirdByte = buf[i + 2] 33359 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { 33360 tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) 33361 if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { 33362 codePoint = tempCodePoint 33363 } 33364 } 33365 break 33366 case 4: 33367 secondByte = buf[i + 1] 33368 thirdByte = buf[i + 2] 33369 fourthByte = buf[i + 3] 33370 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { 33371 tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) 33372 if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { 33373 codePoint = tempCodePoint 33374 } 33375 } 33376 } 33377 } 33378 33379 if (codePoint === null) { 33380 // we did not generate a valid codePoint so insert a 33381 // replacement char (U+FFFD) and advance only 1 byte 33382 codePoint = 0xFFFD 33383 bytesPerSequence = 1 33384 } else if (codePoint > 0xFFFF) { 33385 // encode to utf16 (surrogate pair dance) 33386 codePoint -= 0x10000 33387 res.push(codePoint >>> 10 & 0x3FF | 0xD800) 33388 codePoint = 0xDC00 | codePoint & 0x3FF 33389 } 33390 33391 res.push(codePoint) 33392 i += bytesPerSequence 33393 } 33394 33395 return decodeCodePointsArray(res) 33396} 33397 33398// Based on http://stackoverflow.com/a/22747272/680742, the browser with 33399// the lowest limit is Chrome, with 0x10000 args. 33400// We go 1 magnitude less, for safety 33401var MAX_ARGUMENTS_LENGTH = 0x1000 33402 33403function decodeCodePointsArray (codePoints) { 33404 var len = codePoints.length 33405 if (len <= MAX_ARGUMENTS_LENGTH) { 33406 return String.fromCharCode.apply(String, codePoints) // avoid extra slice() 33407 } 33408 33409 // Decode in chunks to avoid "call stack size exceeded". 33410 var res = '' 33411 var i = 0 33412 while (i < len) { 33413 res += String.fromCharCode.apply( 33414 String, 33415 codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) 33416 ) 33417 } 33418 return res 33419} 33420 33421function asciiSlice (buf, start, end) { 33422 var ret = '' 33423 end = Math.min(buf.length, end) 33424 33425 for (var i = start; i < end; ++i) { 33426 ret += String.fromCharCode(buf[i] & 0x7F) 33427 } 33428 return ret 33429} 33430 33431function latin1Slice (buf, start, end) { 33432 var ret = '' 33433 end = Math.min(buf.length, end) 33434 33435 for (var i = start; i < end; ++i) { 33436 ret += String.fromCharCode(buf[i]) 33437 } 33438 return ret 33439} 33440 33441function hexSlice (buf, start, end) { 33442 var len = buf.length 33443 33444 if (!start || start < 0) start = 0 33445 if (!end || end < 0 || end > len) end = len 33446 33447 var out = '' 33448 for (var i = start; i < end; ++i) { 33449 out += toHex(buf[i]) 33450 } 33451 return out 33452} 33453 33454function utf16leSlice (buf, start, end) { 33455 var bytes = buf.slice(start, end) 33456 var res = '' 33457 for (var i = 0; i < bytes.length; i += 2) { 33458 res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) 33459 } 33460 return res 33461} 33462 33463Buffer.prototype.slice = function slice (start, end) { 33464 var len = this.length 33465 start = ~~start 33466 end = end === undefined ? len : ~~end 33467 33468 if (start < 0) { 33469 start += len 33470 if (start < 0) start = 0 33471 } else if (start > len) { 33472 start = len 33473 } 33474 33475 if (end < 0) { 33476 end += len 33477 if (end < 0) end = 0 33478 } else if (end > len) { 33479 end = len 33480 } 33481 33482 if (end < start) end = start 33483 33484 var newBuf 33485 if (Buffer.TYPED_ARRAY_SUPPORT) { 33486 newBuf = this.subarray(start, end) 33487 newBuf.__proto__ = Buffer.prototype 33488 } else { 33489 var sliceLen = end - start 33490 newBuf = new Buffer(sliceLen, undefined) 33491 for (var i = 0; i < sliceLen; ++i) { 33492 newBuf[i] = this[i + start] 33493 } 33494 } 33495 33496 return newBuf 33497} 33498 33499/* 33500 * Need to make sure that buffer isn't trying to write out of bounds. 33501 */ 33502function checkOffset (offset, ext, length) { 33503 if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') 33504 if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') 33505} 33506 33507Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { 33508 offset = offset | 0 33509 byteLength = byteLength | 0 33510 if (!noAssert) checkOffset(offset, byteLength, this.length) 33511 33512 var val = this[offset] 33513 var mul = 1 33514 var i = 0 33515 while (++i < byteLength && (mul *= 0x100)) { 33516 val += this[offset + i] * mul 33517 } 33518 33519 return val 33520} 33521 33522Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { 33523 offset = offset | 0 33524 byteLength = byteLength | 0 33525 if (!noAssert) { 33526 checkOffset(offset, byteLength, this.length) 33527 } 33528 33529 var val = this[offset + --byteLength] 33530 var mul = 1 33531 while (byteLength > 0 && (mul *= 0x100)) { 33532 val += this[offset + --byteLength] * mul 33533 } 33534 33535 return val 33536} 33537 33538Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { 33539 if (!noAssert) checkOffset(offset, 1, this.length) 33540 return this[offset] 33541} 33542 33543Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { 33544 if (!noAssert) checkOffset(offset, 2, this.length) 33545 return this[offset] | (this[offset + 1] << 8) 33546} 33547 33548Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { 33549 if (!noAssert) checkOffset(offset, 2, this.length) 33550 return (this[offset] << 8) | this[offset + 1] 33551} 33552 33553Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { 33554 if (!noAssert) checkOffset(offset, 4, this.length) 33555 33556 return ((this[offset]) | 33557 (this[offset + 1] << 8) | 33558 (this[offset + 2] << 16)) + 33559 (this[offset + 3] * 0x1000000) 33560} 33561 33562Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { 33563 if (!noAssert) checkOffset(offset, 4, this.length) 33564 33565 return (this[offset] * 0x1000000) + 33566 ((this[offset + 1] << 16) | 33567 (this[offset + 2] << 8) | 33568 this[offset + 3]) 33569} 33570 33571Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { 33572 offset = offset | 0 33573 byteLength = byteLength | 0 33574 if (!noAssert) checkOffset(offset, byteLength, this.length) 33575 33576 var val = this[offset] 33577 var mul = 1 33578 var i = 0 33579 while (++i < byteLength && (mul *= 0x100)) { 33580 val += this[offset + i] * mul 33581 } 33582 mul *= 0x80 33583 33584 if (val >= mul) val -= Math.pow(2, 8 * byteLength) 33585 33586 return val 33587} 33588 33589Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { 33590 offset = offset | 0 33591 byteLength = byteLength | 0 33592 if (!noAssert) checkOffset(offset, byteLength, this.length) 33593 33594 var i = byteLength 33595 var mul = 1 33596 var val = this[offset + --i] 33597 while (i > 0 && (mul *= 0x100)) { 33598 val += this[offset + --i] * mul 33599 } 33600 mul *= 0x80 33601 33602 if (val >= mul) val -= Math.pow(2, 8 * byteLength) 33603 33604 return val 33605} 33606 33607Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { 33608 if (!noAssert) checkOffset(offset, 1, this.length) 33609 if (!(this[offset] & 0x80)) return (this[offset]) 33610 return ((0xff - this[offset] + 1) * -1) 33611} 33612 33613Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { 33614 if (!noAssert) checkOffset(offset, 2, this.length) 33615 var val = this[offset] | (this[offset + 1] << 8) 33616 return (val & 0x8000) ? val | 0xFFFF0000 : val 33617} 33618 33619Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { 33620 if (!noAssert) checkOffset(offset, 2, this.length) 33621 var val = this[offset + 1] | (this[offset] << 8) 33622 return (val & 0x8000) ? val | 0xFFFF0000 : val 33623} 33624 33625Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { 33626 if (!noAssert) checkOffset(offset, 4, this.length) 33627 33628 return (this[offset]) | 33629 (this[offset + 1] << 8) | 33630 (this[offset + 2] << 16) | 33631 (this[offset + 3] << 24) 33632} 33633 33634Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { 33635 if (!noAssert) checkOffset(offset, 4, this.length) 33636 33637 return (this[offset] << 24) | 33638 (this[offset + 1] << 16) | 33639 (this[offset + 2] << 8) | 33640 (this[offset + 3]) 33641} 33642 33643Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { 33644 if (!noAssert) checkOffset(offset, 4, this.length) 33645 return ieee754.read(this, offset, true, 23, 4) 33646} 33647 33648Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { 33649 if (!noAssert) checkOffset(offset, 4, this.length) 33650 return ieee754.read(this, offset, false, 23, 4) 33651} 33652 33653Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { 33654 if (!noAssert) checkOffset(offset, 8, this.length) 33655 return ieee754.read(this, offset, true, 52, 8) 33656} 33657 33658Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { 33659 if (!noAssert) checkOffset(offset, 8, this.length) 33660 return ieee754.read(this, offset, false, 52, 8) 33661} 33662 33663function checkInt (buf, value, offset, ext, max, min) { 33664 if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') 33665 if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') 33666 if (offset + ext > buf.length) throw new RangeError('Index out of range') 33667} 33668 33669Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { 33670 value = +value 33671 offset = offset | 0 33672 byteLength = byteLength | 0 33673 if (!noAssert) { 33674 var maxBytes = Math.pow(2, 8 * byteLength) - 1 33675 checkInt(this, value, offset, byteLength, maxBytes, 0) 33676 } 33677 33678 var mul = 1 33679 var i = 0 33680 this[offset] = value & 0xFF 33681 while (++i < byteLength && (mul *= 0x100)) { 33682 this[offset + i] = (value / mul) & 0xFF 33683 } 33684 33685 return offset + byteLength 33686} 33687 33688Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { 33689 value = +value 33690 offset = offset | 0 33691 byteLength = byteLength | 0 33692 if (!noAssert) { 33693 var maxBytes = Math.pow(2, 8 * byteLength) - 1 33694 checkInt(this, value, offset, byteLength, maxBytes, 0) 33695 } 33696 33697 var i = byteLength - 1 33698 var mul = 1 33699 this[offset + i] = value & 0xFF 33700 while (--i >= 0 && (mul *= 0x100)) { 33701 this[offset + i] = (value / mul) & 0xFF 33702 } 33703 33704 return offset + byteLength 33705} 33706 33707Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { 33708 value = +value 33709 offset = offset | 0 33710 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) 33711 if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 33712 this[offset] = (value & 0xff) 33713 return offset + 1 33714} 33715 33716function objectWriteUInt16 (buf, value, offset, littleEndian) { 33717 if (value < 0) value = 0xffff + value + 1 33718 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { 33719 buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> 33720 (littleEndian ? i : 1 - i) * 8 33721 } 33722} 33723 33724Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { 33725 value = +value 33726 offset = offset | 0 33727 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 33728 if (Buffer.TYPED_ARRAY_SUPPORT) { 33729 this[offset] = (value & 0xff) 33730 this[offset + 1] = (value >>> 8) 33731 } else { 33732 objectWriteUInt16(this, value, offset, true) 33733 } 33734 return offset + 2 33735} 33736 33737Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { 33738 value = +value 33739 offset = offset | 0 33740 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 33741 if (Buffer.TYPED_ARRAY_SUPPORT) { 33742 this[offset] = (value >>> 8) 33743 this[offset + 1] = (value & 0xff) 33744 } else { 33745 objectWriteUInt16(this, value, offset, false) 33746 } 33747 return offset + 2 33748} 33749 33750function objectWriteUInt32 (buf, value, offset, littleEndian) { 33751 if (value < 0) value = 0xffffffff + value + 1 33752 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { 33753 buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff 33754 } 33755} 33756 33757Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { 33758 value = +value 33759 offset = offset | 0 33760 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 33761 if (Buffer.TYPED_ARRAY_SUPPORT) { 33762 this[offset + 3] = (value >>> 24) 33763 this[offset + 2] = (value >>> 16) 33764 this[offset + 1] = (value >>> 8) 33765 this[offset] = (value & 0xff) 33766 } else { 33767 objectWriteUInt32(this, value, offset, true) 33768 } 33769 return offset + 4 33770} 33771 33772Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { 33773 value = +value 33774 offset = offset | 0 33775 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 33776 if (Buffer.TYPED_ARRAY_SUPPORT) { 33777 this[offset] = (value >>> 24) 33778 this[offset + 1] = (value >>> 16) 33779 this[offset + 2] = (value >>> 8) 33780 this[offset + 3] = (value & 0xff) 33781 } else { 33782 objectWriteUInt32(this, value, offset, false) 33783 } 33784 return offset + 4 33785} 33786 33787Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { 33788 value = +value 33789 offset = offset | 0 33790 if (!noAssert) { 33791 var limit = Math.pow(2, 8 * byteLength - 1) 33792 33793 checkInt(this, value, offset, byteLength, limit - 1, -limit) 33794 } 33795 33796 var i = 0 33797 var mul = 1 33798 var sub = 0 33799 this[offset] = value & 0xFF 33800 while (++i < byteLength && (mul *= 0x100)) { 33801 if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { 33802 sub = 1 33803 } 33804 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 33805 } 33806 33807 return offset + byteLength 33808} 33809 33810Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { 33811 value = +value 33812 offset = offset | 0 33813 if (!noAssert) { 33814 var limit = Math.pow(2, 8 * byteLength - 1) 33815 33816 checkInt(this, value, offset, byteLength, limit - 1, -limit) 33817 } 33818 33819 var i = byteLength - 1 33820 var mul = 1 33821 var sub = 0 33822 this[offset + i] = value & 0xFF 33823 while (--i >= 0 && (mul *= 0x100)) { 33824 if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { 33825 sub = 1 33826 } 33827 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 33828 } 33829 33830 return offset + byteLength 33831} 33832 33833Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { 33834 value = +value 33835 offset = offset | 0 33836 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) 33837 if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 33838 if (value < 0) value = 0xff + value + 1 33839 this[offset] = (value & 0xff) 33840 return offset + 1 33841} 33842 33843Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { 33844 value = +value 33845 offset = offset | 0 33846 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 33847 if (Buffer.TYPED_ARRAY_SUPPORT) { 33848 this[offset] = (value & 0xff) 33849 this[offset + 1] = (value >>> 8) 33850 } else { 33851 objectWriteUInt16(this, value, offset, true) 33852 } 33853 return offset + 2 33854} 33855 33856Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { 33857 value = +value 33858 offset = offset | 0 33859 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 33860 if (Buffer.TYPED_ARRAY_SUPPORT) { 33861 this[offset] = (value >>> 8) 33862 this[offset + 1] = (value & 0xff) 33863 } else { 33864 objectWriteUInt16(this, value, offset, false) 33865 } 33866 return offset + 2 33867} 33868 33869Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { 33870 value = +value 33871 offset = offset | 0 33872 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 33873 if (Buffer.TYPED_ARRAY_SUPPORT) { 33874 this[offset] = (value & 0xff) 33875 this[offset + 1] = (value >>> 8) 33876 this[offset + 2] = (value >>> 16) 33877 this[offset + 3] = (value >>> 24) 33878 } else { 33879 objectWriteUInt32(this, value, offset, true) 33880 } 33881 return offset + 4 33882} 33883 33884Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { 33885 value = +value 33886 offset = offset | 0 33887 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 33888 if (value < 0) value = 0xffffffff + value + 1 33889 if (Buffer.TYPED_ARRAY_SUPPORT) { 33890 this[offset] = (value >>> 24) 33891 this[offset + 1] = (value >>> 16) 33892 this[offset + 2] = (value >>> 8) 33893 this[offset + 3] = (value & 0xff) 33894 } else { 33895 objectWriteUInt32(this, value, offset, false) 33896 } 33897 return offset + 4 33898} 33899 33900function checkIEEE754 (buf, value, offset, ext, max, min) { 33901 if (offset + ext > buf.length) throw new RangeError('Index out of range') 33902 if (offset < 0) throw new RangeError('Index out of range') 33903} 33904 33905function writeFloat (buf, value, offset, littleEndian, noAssert) { 33906 if (!noAssert) { 33907 checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) 33908 } 33909 ieee754.write(buf, value, offset, littleEndian, 23, 4) 33910 return offset + 4 33911} 33912 33913Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { 33914 return writeFloat(this, value, offset, true, noAssert) 33915} 33916 33917Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { 33918 return writeFloat(this, value, offset, false, noAssert) 33919} 33920 33921function writeDouble (buf, value, offset, littleEndian, noAssert) { 33922 if (!noAssert) { 33923 checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) 33924 } 33925 ieee754.write(buf, value, offset, littleEndian, 52, 8) 33926 return offset + 8 33927} 33928 33929Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { 33930 return writeDouble(this, value, offset, true, noAssert) 33931} 33932 33933Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { 33934 return writeDouble(this, value, offset, false, noAssert) 33935} 33936 33937// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) 33938Buffer.prototype.copy = function copy (target, targetStart, start, end) { 33939 if (!start) start = 0 33940 if (!end && end !== 0) end = this.length 33941 if (targetStart >= target.length) targetStart = target.length 33942 if (!targetStart) targetStart = 0 33943 if (end > 0 && end < start) end = start 33944 33945 // Copy 0 bytes; we're done 33946 if (end === start) return 0 33947 if (target.length === 0 || this.length === 0) return 0 33948 33949 // Fatal error conditions 33950 if (targetStart < 0) { 33951 throw new RangeError('targetStart out of bounds') 33952 } 33953 if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') 33954 if (end < 0) throw new RangeError('sourceEnd out of bounds') 33955 33956 // Are we oob? 33957 if (end > this.length) end = this.length 33958 if (target.length - targetStart < end - start) { 33959 end = target.length - targetStart + start 33960 } 33961 33962 var len = end - start 33963 var i 33964 33965 if (this === target && start < targetStart && targetStart < end) { 33966 // descending copy from end 33967 for (i = len - 1; i >= 0; --i) { 33968 target[i + targetStart] = this[i + start] 33969 } 33970 } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { 33971 // ascending copy from start 33972 for (i = 0; i < len; ++i) { 33973 target[i + targetStart] = this[i + start] 33974 } 33975 } else { 33976 Uint8Array.prototype.set.call( 33977 target, 33978 this.subarray(start, start + len), 33979 targetStart 33980 ) 33981 } 33982 33983 return len 33984} 33985 33986// Usage: 33987// buffer.fill(number[, offset[, end]]) 33988// buffer.fill(buffer[, offset[, end]]) 33989// buffer.fill(string[, offset[, end]][, encoding]) 33990Buffer.prototype.fill = function fill (val, start, end, encoding) { 33991 // Handle string cases: 33992 if (typeof val === 'string') { 33993 if (typeof start === 'string') { 33994 encoding = start 33995 start = 0 33996 end = this.length 33997 } else if (typeof end === 'string') { 33998 encoding = end 33999 end = this.length 34000 } 34001 if (val.length === 1) { 34002 var code = val.charCodeAt(0) 34003 if (code < 256) { 34004 val = code 34005 } 34006 } 34007 if (encoding !== undefined && typeof encoding !== 'string') { 34008 throw new TypeError('encoding must be a string') 34009 } 34010 if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { 34011 throw new TypeError('Unknown encoding: ' + encoding) 34012 } 34013 } else if (typeof val === 'number') { 34014 val = val & 255 34015 } 34016 34017 // Invalid ranges are not set to a default, so can range check early. 34018 if (start < 0 || this.length < start || this.length < end) { 34019 throw new RangeError('Out of range index') 34020 } 34021 34022 if (end <= start) { 34023 return this 34024 } 34025 34026 start = start >>> 0 34027 end = end === undefined ? this.length : end >>> 0 34028 34029 if (!val) val = 0 34030 34031 var i 34032 if (typeof val === 'number') { 34033 for (i = start; i < end; ++i) { 34034 this[i] = val 34035 } 34036 } else { 34037 var bytes = Buffer.isBuffer(val) 34038 ? val 34039 : utf8ToBytes(new Buffer(val, encoding).toString()) 34040 var len = bytes.length 34041 for (i = 0; i < end - start; ++i) { 34042 this[i + start] = bytes[i % len] 34043 } 34044 } 34045 34046 return this 34047} 34048 34049// HELPER FUNCTIONS 34050// ================ 34051 34052var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g 34053 34054function base64clean (str) { 34055 // Node strips out invalid characters like \n and \t from the string, base64-js does not 34056 str = stringtrim(str).replace(INVALID_BASE64_RE, '') 34057 // Node converts strings with length < 2 to '' 34058 if (str.length < 2) return '' 34059 // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not 34060 while (str.length % 4 !== 0) { 34061 str = str + '=' 34062 } 34063 return str 34064} 34065 34066function stringtrim (str) { 34067 if (str.trim) return str.trim() 34068 return str.replace(/^\s+|\s+$/g, '') 34069} 34070 34071function toHex (n) { 34072 if (n < 16) return '0' + n.toString(16) 34073 return n.toString(16) 34074} 34075 34076function utf8ToBytes (string, units) { 34077 units = units || Infinity 34078 var codePoint 34079 var length = string.length 34080 var leadSurrogate = null 34081 var bytes = [] 34082 34083 for (var i = 0; i < length; ++i) { 34084 codePoint = string.charCodeAt(i) 34085 34086 // is surrogate component 34087 if (codePoint > 0xD7FF && codePoint < 0xE000) { 34088 // last char was a lead 34089 if (!leadSurrogate) { 34090 // no lead yet 34091 if (codePoint > 0xDBFF) { 34092 // unexpected trail 34093 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 34094 continue 34095 } else if (i + 1 === length) { 34096 // unpaired lead 34097 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 34098 continue 34099 } 34100 34101 // valid lead 34102 leadSurrogate = codePoint 34103 34104 continue 34105 } 34106 34107 // 2 leads in a row 34108 if (codePoint < 0xDC00) { 34109 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 34110 leadSurrogate = codePoint 34111 continue 34112 } 34113 34114 // valid surrogate pair 34115 codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 34116 } else if (leadSurrogate) { 34117 // valid bmp char, but last char was a lead 34118 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 34119 } 34120 34121 leadSurrogate = null 34122 34123 // encode utf8 34124 if (codePoint < 0x80) { 34125 if ((units -= 1) < 0) break 34126 bytes.push(codePoint) 34127 } else if (codePoint < 0x800) { 34128 if ((units -= 2) < 0) break 34129 bytes.push( 34130 codePoint >> 0x6 | 0xC0, 34131 codePoint & 0x3F | 0x80 34132 ) 34133 } else if (codePoint < 0x10000) { 34134 if ((units -= 3) < 0) break 34135 bytes.push( 34136 codePoint >> 0xC | 0xE0, 34137 codePoint >> 0x6 & 0x3F | 0x80, 34138 codePoint & 0x3F | 0x80 34139 ) 34140 } else if (codePoint < 0x110000) { 34141 if ((units -= 4) < 0) break 34142 bytes.push( 34143 codePoint >> 0x12 | 0xF0, 34144 codePoint >> 0xC & 0x3F | 0x80, 34145 codePoint >> 0x6 & 0x3F | 0x80, 34146 codePoint & 0x3F | 0x80 34147 ) 34148 } else { 34149 throw new Error('Invalid code point') 34150 } 34151 } 34152 34153 return bytes 34154} 34155 34156function asciiToBytes (str) { 34157 var byteArray = [] 34158 for (var i = 0; i < str.length; ++i) { 34159 // Node's code seems to be doing this and not & 0x7F.. 34160 byteArray.push(str.charCodeAt(i) & 0xFF) 34161 } 34162 return byteArray 34163} 34164 34165function utf16leToBytes (str, units) { 34166 var c, hi, lo 34167 var byteArray = [] 34168 for (var i = 0; i < str.length; ++i) { 34169 if ((units -= 2) < 0) break 34170 34171 c = str.charCodeAt(i) 34172 hi = c >> 8 34173 lo = c % 256 34174 byteArray.push(lo) 34175 byteArray.push(hi) 34176 } 34177 34178 return byteArray 34179} 34180 34181function base64ToBytes (str) { 34182 return base64.toByteArray(base64clean(str)) 34183} 34184 34185function blitBuffer (src, dst, offset, length) { 34186 for (var i = 0; i < length; ++i) { 34187 if ((i + offset >= dst.length) || (i >= src.length)) break 34188 dst[i + offset] = src[i] 34189 } 34190 return i 34191} 34192 34193function isnan (val) { 34194 return val !== val // eslint-disable-line no-self-compare 34195} 34196 34197/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(
vendor: 4,037 bytes, lines 34197-34357
341972))) 34198 34199/***/ }), 34200/* 18 */ 34201/***/ (function(module, exports, __webpack_require__) { 34202 34203"use strict"; 34204 34205 34206exports.byteLength = byteLength 34207exports.toByteArray = toByteArray 34208exports.fromByteArray = fromByteArray 34209 34210var lookup = [] 34211var revLookup = [] 34212var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array 34213 34214var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' 34215for (var i = 0, len = code.length; i < len; ++i) { 34216 lookup[i] = code[i] 34217 revLookup[code.charCodeAt(i)] = i 34218} 34219 34220// Support decoding URL-safe base64 strings, as Node.js does. 34221// See: https://en.wikipedia.org/wiki/Base64#URL_applications 34222revLookup['-'.charCodeAt(0)] = 62 34223revLookup['_'.charCodeAt(0)] = 63 34224 34225function getLens (b64) { 34226 var len = b64.length 34227 34228 if (len % 4 > 0) { 34229 throw new Error('Invalid string. Length must be a multiple of 4') 34230 } 34231 34232 // Trim off extra bytes after placeholder bytes are found 34233 // See: https://github.com/beatgammit/base64-js/issues/42 34234 var validLen = b64.indexOf('=') 34235 if (validLen === -1) validLen = len 34236 34237 var placeHoldersLen = validLen === len 34238 ? 0 34239 : 4 - (validLen % 4) 34240 34241 return [validLen, placeHoldersLen] 34242} 34243 34244// base64 is 4/3 + up to two characters of the original data 34245function byteLength (b64) { 34246 var lens = getLens(b64) 34247 var validLen = lens[0] 34248 var placeHoldersLen = lens[1] 34249 return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen 34250} 34251 34252function _byteLength (b64, validLen, placeHoldersLen) { 34253 return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen 34254} 34255 34256function toByteArray (b64) { 34257 var tmp 34258 var lens = getLens(b64) 34259 var validLen = lens[0] 34260 var placeHoldersLen = lens[1] 34261 34262 var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) 34263 34264 var curByte = 0 34265 34266 // if there are placeholders, only get up to the last complete 4 chars 34267 var len = placeHoldersLen > 0 34268 ? validLen - 4 34269 : validLen 34270 34271 var i 34272 for (i = 0; i < len; i += 4) { 34273 tmp = 34274 (revLookup[b64.charCodeAt(i)] << 18) | 34275 (revLookup[b64.charCodeAt(i + 1)] << 12) | 34276 (revLookup[b64.charCodeAt(i + 2)] << 6) | 34277 revLookup[b64.charCodeAt(i + 3)] 34278 arr[curByte++] = (tmp >> 16) & 0xFF 34279 arr[curByte++] = (tmp >> 8) & 0xFF 34280 arr[curByte++] = tmp & 0xFF 34281 } 34282 34283 if (placeHoldersLen === 2) { 34284 tmp = 34285 (revLookup[b64.charCodeAt(i)] << 2) | 34286 (revLookup[b64.charCodeAt(i + 1)] >> 4) 34287 arr[curByte++] = tmp & 0xFF 34288 } 34289 34290 if (placeHoldersLen === 1) { 34291 tmp = 34292 (revLookup[b64.charCodeAt(i)] << 10) | 34293 (revLookup[b64.charCodeAt(i + 1)] << 4) | 34294 (revLookup[b64.charCodeAt(i + 2)] >> 2) 34295 arr[curByte++] = (tmp >> 8) & 0xFF 34296 arr[curByte++] = tmp & 0xFF 34297 } 34298 34299 return arr 34300} 34301 34302function tripletToBase64 (num) { 34303 return lookup[num >> 18 & 0x3F] + 34304 lookup[num >> 12 & 0x3F] + 34305 lookup[num >> 6 & 0x3F] + 34306 lookup[num & 0x3F] 34307} 34308 34309function encodeChunk (uint8, start, end) { 34310 var tmp 34311 var output = [] 34312 for (var i = start; i < end; i += 3) { 34313 tmp = 34314 ((uint8[i] << 16) & 0xFF0000) + 34315 ((uint8[i + 1] << 8) & 0xFF00) + 34316 (uint8[i + 2] & 0xFF) 34317 output.push(tripletToBase64(tmp)) 34318 } 34319 return output.join('') 34320} 34321 34322function fromByteArray (uint8) { 34323 var tmp 34324 var len = uint8.length 34325 var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes 34326 var parts = [] 34327 var maxChunkLength = 16383 // must be multiple of 3 34328 34329 // go through the array every three bytes, we'll deal with trailing stuff later 34330 for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { 34331 parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) 34332 } 34333 34334 // pad the end with zeros, but make sure to not forget the extra bytes 34335 if (extraBytes === 1) { 34336 tmp = uint8[len - 1] 34337 parts.push( 34338 lookup[tmp >> 2] + 34339 lookup[(tmp << 4) & 0x3F] + 34340 '==' 34341 ) 34342 } else if (extraBytes === 2) { 34343 tmp = (uint8[len - 2] << 8) + uint8[len - 1] 34344 parts.push( 34345 lookup[tmp >> 10] + 34346 lookup[(tmp >> 4) & 0x3F] + 34347 lookup[(tmp << 2) & 0x3F] + 34348 '=' 34349 ) 34350 } 34351 34352 return parts.join('') 34353} 34354 34355 34356/***/ }), 34357/* 19 */
vendor: 4,950 bytes, lines 34358-34541
34358/***/ (function(module, exports) { 34359 34360/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */ 34361exports.read = function (buffer, offset, isLE, mLen, nBytes) { 34362 var e, m 34363 var eLen = (nBytes * 8) - mLen - 1 34364 var eMax = (1 << eLen) - 1 34365 var eBias = eMax >> 1 34366 var nBits = -7 34367 var i = isLE ? (nBytes - 1) : 0 34368 var d = isLE ? -1 : 1 34369 var s = buffer[offset + i] 34370 34371 i += d 34372 34373 e = s & ((1 << (-nBits)) - 1) 34374 s >>= (-nBits) 34375 nBits += eLen 34376 for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} 34377 34378 m = e & ((1 << (-nBits)) - 1) 34379 e >>= (-nBits) 34380 nBits += mLen 34381 for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} 34382 34383 if (e === 0) { 34384 e = 1 - eBias 34385 } else if (e === eMax) { 34386 return m ? NaN : ((s ? -1 : 1) * Infinity) 34387 } else { 34388 m = m + Math.pow(2, mLen) 34389 e = e - eBias 34390 } 34391 return (s ? -1 : 1) * m * Math.pow(2, e - mLen) 34392} 34393 34394exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { 34395 var e, m, c 34396 var eLen = (nBytes * 8) - mLen - 1 34397 var eMax = (1 << eLen) - 1 34398 var eBias = eMax >> 1 34399 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) 34400 var i = isLE ? 0 : (nBytes - 1) 34401 var d = isLE ? 1 : -1 34402 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 34403 34404 value = Math.abs(value) 34405 34406 if (isNaN(value) || value === Infinity) { 34407 m = isNaN(value) ? 1 : 0 34408 e = eMax 34409 } else { 34410 e = Math.floor(Math.log(value) / Math.LN2) 34411 if (value * (c = Math.pow(2, -e)) < 1) { 34412 e-- 34413 c *= 2 34414 } 34415 if (e + eBias >= 1) { 34416 value += rt / c 34417 } else { 34418 value += rt * Math.pow(2, 1 - eBias) 34419 } 34420 if (value * c >= 2) { 34421 e++ 34422 c /= 2 34423 } 34424 34425 if (e + eBias >= eMax) { 34426 m = 0 34427 e = eMax 34428 } else if (e + eBias >= 1) { 34429 m = ((value * c) - 1) * Math.pow(2, mLen) 34430 e = e + eBias 34431 } else { 34432 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) 34433 e = 0 34434 } 34435 } 34436 34437 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} 34438 34439 e = (e << mLen) | m 34440 eLen += mLen 34441 for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} 34442 34443 buffer[offset + i - d] |= s * 128 34444} 34445 34446 34447/***/ }), 34448/* 20 */ 34449/***/ (function(module, exports) { 34450 34451var toString = {}.toString; 34452 34453module.exports = Array.isArray || function (arr) { 34454 return toString.call(arr) == '[object Array]'; 34455}; 34456 34457 34458/***/ }), 34459/* 21 */ 34460/***/ (function(module, exports, __webpack_require__) { 34461 34462/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) || 34463 (typeof self !== "undefined" && self) || 34464 window; 34465var apply = Function.prototype.apply; 34466 34467// DOM APIs, for completeness 34468 34469exports.setTimeout = function() { 34470 return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout); 34471}; 34472exports.setInterval = function() { 34473 return new Timeout(apply.call(setInterval, scope, arguments), clearInterval); 34474}; 34475exports.clearTimeout = 34476exports.clearInterval = function(timeout) { 34477 if (timeout) { 34478 timeout.close(); 34479 } 34480}; 34481 34482function Timeout(id, clearFn) { 34483 this._id = id; 34484 this._clearFn = clearFn; 34485} 34486Timeout.prototype.unref = Timeout.prototype.ref = function() {}; 34487Timeout.prototype.close = function() { 34488 this._clearFn.call(scope, this._id); 34489}; 34490 34491// Does not start the time, just sets up the members needed. 34492exports.enroll = function(item, msecs) { 34493 clearTimeout(item._idleTimeoutId); 34494 item._idleTimeout = msecs; 34495}; 34496 34497exports.unenroll = function(item) { 34498 clearTimeout(item._idleTimeoutId); 34499 item._idleTimeout = -1; 34500}; 34501 34502exports._unrefActive = exports.active = function(item) { 34503 clearTimeout(item._idleTimeoutId); 34504 34505 var msecs = item._idleTimeout; 34506 if (msecs >= 0) { 34507 item._idleTimeoutId = setTimeout(function onTimeout() { 34508 if (item._onTimeout) 34509 item._onTimeout(); 34510 }, msecs); 34511 } 34512}; 34513 34514// setimmediate attaches itself to the global object 34515__webpack_require__(22); 34516// On some exotic environments, it's not clear which object `setimmediate` was 34517// able to install onto. Search each possibility in the same order as the 34518// `setimmediate` library. 34519exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) || 34520 (typeof global !== "undefined" && global.setImmediate) || 34521 (this && this.setImmediate); 34522exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) || 34523 (typeof global !== "undefined" && global.clearImmediate) || 34524 (this && this.clearImmediate); 34525 34526/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2))) 34527 34528/***/ }), 34529/* 22 */ 34530/***/ (function(module, exports, __webpack_require__) { 34531 34532/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { 34533 "use strict"; 34534 34535 if (global.setImmediate) { 34536 return; 34537 } 34538 34539 var nextHandle = 1; // Spec says greater than zero 34540 var tasksByHandle = {}; 34541 var currentlyRunningATask = false;
vendor: 5,701 bytes, lines 34542-34702
34542 var doc = global.document; 34543 var registerImmediate; 34544 34545 function setImmediate(callback) { 34546 // Callback can either be a function or a string 34547 if (typeof callback !== "function") { 34548 callback = new Function("" + callback); 34549 } 34550 // Copy function arguments 34551 var args = new Array(arguments.length - 1); 34552 for (var i = 0; i < args.length; i++) { 34553 args[i] = arguments[i + 1]; 34554 } 34555 // Store and register the task 34556 var task = { callback: callback, args: args }; 34557 tasksByHandle[nextHandle] = task; 34558 registerImmediate(nextHandle); 34559 return nextHandle++; 34560 } 34561 34562 function clearImmediate(handle) { 34563 delete tasksByHandle[handle]; 34564 } 34565 34566 function run(task) { 34567 var callback = task.callback; 34568 var args = task.args; 34569 switch (args.length) { 34570 case 0: 34571 callback(); 34572 break; 34573 case 1: 34574 callback(args[0]); 34575 break; 34576 case 2: 34577 callback(args[0], args[1]); 34578 break; 34579 case 3: 34580 callback(args[0], args[1], args[2]); 34581 break; 34582 default: 34583 callback.apply(undefined, args); 34584 break; 34585 } 34586 } 34587 34588 function runIfPresent(handle) { 34589 // From the spec: "Wait until any invocations of this algorithm started before this one have completed." 34590 // So if we're currently running a task, we'll need to delay this invocation. 34591 if (currentlyRunningATask) { 34592 // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a 34593 // "too much recursion" error. 34594 setTimeout(runIfPresent, 0, handle); 34595 } else { 34596 var task = tasksByHandle[handle]; 34597 if (task) { 34598 currentlyRunningATask = true; 34599 try { 34600 run(task); 34601 } finally { 34602 clearImmediate(handle); 34603 currentlyRunningATask = false; 34604 } 34605 } 34606 } 34607 } 34608 34609 function installNextTickImplementation() { 34610 registerImmediate = function(handle) { 34611 process.nextTick(function () { runIfPresent(handle); }); 34612 }; 34613 } 34614 34615 function canUsePostMessage() { 34616 // The test against `importScripts` prevents this implementation from being installed inside a web worker, 34617 // where `global.postMessage` means something completely different and can't be used for this purpose. 34618 if (global.postMessage && !global.importScripts) { 34619 var postMessageIsAsynchronous = true; 34620 var oldOnMessage = global.onmessage; 34621 global.onmessage = function() { 34622 postMessageIsAsynchronous = false; 34623 }; 34624 global.postMessage("", "*"); 34625 global.onmessage = oldOnMessage; 34626 return postMessageIsAsynchronous; 34627 } 34628 } 34629 34630 function installPostMessageImplementation() { 34631 // Installs an event handler on `global` for the `message` event: see 34632 // * https://developer.mozilla.org/en/DOM/window.postMessage 34633 // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages 34634 34635 var messagePrefix = "setImmediate$" + Math.random() + "$"; 34636 var onGlobalMessage = function(event) { 34637 if (event.source === global && 34638 typeof event.data === "string" && 34639 event.data.indexOf(messagePrefix) === 0) { 34640 runIfPresent(+event.data.slice(messagePrefix.length)); 34641 } 34642 }; 34643 34644 if (global.addEventListener) { 34645 global.addEventListener("message", onGlobalMessage, false); 34646 } else { 34647 global.attachEvent("onmessage", onGlobalMessage); 34648 } 34649 34650 registerImmediate = function(handle) { 34651 global.postMessage(messagePrefix + handle, "*"); 34652 }; 34653 } 34654 34655 function installMessageChannelImplementation() { 34656 var channel = new MessageChannel(); 34657 channel.port1.onmessage = function(event) { 34658 var handle = event.data; 34659 runIfPresent(handle); 34660 }; 34661 34662 registerImmediate = function(handle) { 34663 channel.port2.postMessage(handle); 34664 }; 34665 } 34666 34667 function installReadyStateChangeImplementation() { 34668 var html = doc.documentElement; 34669 registerImmediate = function(handle) { 34670 // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted 34671 // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. 34672 var script = doc.createElement("script"); 34673 script.onreadystatechange = function () { 34674 runIfPresent(handle); 34675 script.onreadystatechange = null; 34676 html.removeChild(script); 34677 script = null; 34678 }; 34679 html.appendChild(script); 34680 }; 34681 } 34682 34683 function installSetTimeoutImplementation() { 34684 registerImmediate = function(handle) { 34685 setTimeout(runIfPresent, 0, handle); 34686 }; 34687 } 34688 34689 // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live. 34690 var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global); 34691 attachTo = attachTo && attachTo.setTimeout ? attachTo : global; 34692 34693 // Don't get fooled by e.g. browserify environments. 34694 if ({}.toString.call(global.process) === "[object process]") { 34695 // For Node.js before 0.9 34696 installNextTickImplementation(); 34697 34698 } else if (canUsePostMessage()) { 34699 // For non-IE10 modern browsers 34700 installPostMessageImplementation(); 34701 34702 }
vendor: 4,139 bytes, lines 34702-34823
34702 else if (global.MessageChannel) { 34703 // For web workers, where supported 34704 installMessageChannelImplementation(); 34705 34706 } else if (doc && "onreadystatechange" in doc.createElement("script")) { 34707 // For IE 6â8 34708 installReadyStateChangeImplementation(); 34709 34710 } else { 34711 // For older browsers 34712 installSetTimeoutImplementation(); 34713 } 34714 34715 attachTo.setImmediate = setImmediate; 34716 attachTo.clearImmediate = clearImmediate; 34717}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self)); 34718 34719/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2), __webpack_require__(23))) 34720 34721/***/ }), 34722/* 23 */ 34723/***/ (function(module, exports) { 34724 34725// shim for using process in browser 34726var process = module.exports = {}; 34727 34728// cached from whatever global is present so that test runners that stub it 34729// don't break things. But we need to wrap it in a try catch in case it is 34730// wrapped in strict mode code which doesn't define any globals. It's inside a 34731// function because try/catches deoptimize in certain engines. 34732 34733var cachedSetTimeout; 34734var cachedClearTimeout; 34735 34736function defaultSetTimout() { 34737 throw new Error('setTimeout has not been defined'); 34738} 34739function defaultClearTimeout () { 34740 throw new Error('clearTimeout has not been defined'); 34741} 34742(function () { 34743 try { 34744 if (typeof setTimeout === 'function') { 34745 cachedSetTimeout = setTimeout; 34746 } else { 34747 cachedSetTimeout = defaultSetTimout; 34748 } 34749 } catch (e) { 34750 cachedSetTimeout = defaultSetTimout; 34751 } 34752 try { 34753 if (typeof clearTimeout === 'function') { 34754 cachedClearTimeout = clearTimeout; 34755 } else { 34756 cachedClearTimeout = defaultClearTimeout; 34757 } 34758 } catch (e) { 34759 cachedClearTimeout = defaultClearTimeout; 34760 } 34761} ()) 34762function runTimeout(fun) { 34763 if (cachedSetTimeout === setTimeout) { 34764 //normal enviroments in sane situations 34765 return setTimeout(fun, 0); 34766 } 34767 // if setTimeout wasn't available but was latter defined 34768 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 34769 cachedSetTimeout = setTimeout; 34770 return setTimeout(fun, 0); 34771 } 34772 try { 34773 // when when somebody has screwed with setTimeout but no I.E. maddness 34774 return cachedSetTimeout(fun, 0); 34775 } catch(e){ 34776 try { 34777 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 34778 return cachedSetTimeout.call(null, fun, 0); 34779 } catch(e){ 34780 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 34781 return cachedSetTimeout.call(this, fun, 0); 34782 } 34783 } 34784 34785 34786} 34787function runClearTimeout(marker) { 34788 if (cachedClearTimeout === clearTimeout) { 34789 //normal enviroments in sane situations 34790 return clearTimeout(marker); 34791 } 34792 // if clearTimeout wasn't available but was latter defined 34793 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 34794 cachedClearTimeout = clearTimeout; 34795 return clearTimeout(marker); 34796 } 34797 try { 34798 // when when somebody has screwed with setTimeout but no I.E. maddness 34799 return cachedClearTimeout(marker); 34800 } catch (e){ 34801 try { 34802 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 34803 return cachedClearTimeout.call(null, marker); 34804 } catch (e){ 34805 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 34806 // Some versions of I.E. have different rules for clearTimeout vs setTimeout 34807 return cachedClearTimeout.call(this, marker); 34808 } 34809 } 34810 34811 34812 34813} 34814var queue = []; 34815var draining = false; 34816var currentQueue; 34817var queueIndex = -1; 34818 34819function cleanUpNextTick() { 34820 if (!draining || !currentQueue) { 34821 return; 34822 } 34823 draining = false;
vendor: 2,164 bytes, lines 34824-34925
34824 if (currentQueue.length) { 34825 queue = currentQueue.concat(queue); 34826 } else { 34827 queueIndex = -1; 34828 } 34829 if (queue.length) { 34830 drainQueue(); 34831 } 34832} 34833 34834function drainQueue() { 34835 if (draining) { 34836 return; 34837 } 34838 var timeout = runTimeout(cleanUpNextTick); 34839 draining = true; 34840 34841 var len = queue.length; 34842 while(len) { 34843 currentQueue = queue; 34844 queue = []; 34845 while (++queueIndex < len) { 34846 if (currentQueue) { 34847 currentQueue[queueIndex].run(); 34848 } 34849 } 34850 queueIndex = -1; 34851 len = queue.length; 34852 } 34853 currentQueue = null; 34854 draining = false; 34855 runClearTimeout(timeout); 34856} 34857 34858process.nextTick = function (fun) { 34859 var args = new Array(arguments.length - 1); 34860 if (arguments.length > 1) { 34861 for (var i = 1; i < arguments.length; i++) { 34862 args[i - 1] = arguments[i]; 34863 } 34864 } 34865 queue.push(new Item(fun, args)); 34866 if (queue.length === 1 && !draining) { 34867 runTimeout(drainQueue); 34868 } 34869}; 34870 34871// v8 likes predictible objects 34872function Item(fun, array) { 34873 this.fun = fun; 34874 this.array = array; 34875} 34876Item.prototype.run = function () { 34877 this.fun.apply(null, this.array); 34878}; 34879process.title = 'browser'; 34880process.browser = true; 34881process.env = {}; 34882process.argv = []; 34883process.version = ''; // empty string to avoid regexp issues 34884process.versions = {}; 34885 34886function noop() {} 34887 34888process.on = noop; 34889process.addListener = noop; 34890process.once = noop; 34891process.off = noop; 34892process.removeListener = noop; 34893process.removeAllListeners = noop; 34894process.emit = noop; 34895process.prependListener = noop; 34896process.prependOnceListener = noop; 34897 34898process.listeners = function (name) { return [] } 34899 34900process.binding = function (name) { 34901 throw new Error('process.binding is not supported'); 34902}; 34903 34904process.cwd = function () { return '/' }; 34905process.chdir = function (dir) { 34906 throw new Error('process.chdir is not supported'); 34907}; 34908process.umask = function() { return 0; }; 34909 34910 34911/***/ }), 34912/* 24 */, 34913/* 25 */, 34914/* 26 */, 34915/* 27 */, 34916/* 28 */, 34917/* 29 */, 34918/* 30 */, 34919/* 31 */ 34920/***/ (function(module, exports) { 34921 34922// removed by extract-text-webpack-plugin 34923 34924/***/ }) 34925/******/ ]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.